contrib modules security updates

This commit is contained in:
Bachir Soussi Chiadmi
2016-10-13 12:10:40 +02:00
parent ffd758abc9
commit 747127f643
732 changed files with 67976 additions and 23207 deletions

View File

@@ -32,6 +32,7 @@ class CommonSyndicationParserTestCase extends DrupalWebTestCase {
$this->_testRSS10();
$this->_testRSS2();
$this->_testAtomGeoRSS();
$this->_testAtomGeoRSSWithoutAuthor();
}
/**
@@ -82,6 +83,14 @@ class CommonSyndicationParserTestCase extends DrupalWebTestCase {
$this->assertEqual($feed['items'][3]['geolocations'][0]['lon'], '172.5902');
}
/**
* Tests parsing an Atom feed without an author.
*/
protected function _testAtomGeoRSSWithoutAuthor() {
$string = $this->readFeed('earthquake-georss-noauthor.atom');
$feed = common_syndication_parser_parse($string);
}
/**
* Helper to read a feed.
*/

View File

@@ -18,11 +18,11 @@ class FeedsWebTestCase extends DrupalWebTestCase {
// array of module names to setUp().
if (isset($args[0])) {
if (is_array($args[0])) {
$modules = $args[0];
}
$modules = $args[0];
}
else {
$modules = $args;
}
$modules = $args;
}
}
else {
$modules = array();
@@ -89,6 +89,7 @@ class FeedsWebTestCase extends DrupalWebTestCase {
$permissions[] = 'administer taxonomy';
$permissions[] = 'administer users';
$permissions[] = 'administer feeds';
$permissions[] = 'administer filters';
// Create an admin user and log in.
$this->admin_user = $this->drupalCreateUser($permissions);
@@ -188,6 +189,8 @@ class FeedsWebTestCase extends DrupalWebTestCase {
$this->assertPlugins($id, 'FeedsHTTPFetcher', 'FeedsSyndicationParser', 'FeedsNodeProcessor');
// Per default attach to page content type.
$this->setSettings($id, NULL, array('content_type' => 'page'));
// Per default attached to article content type.
$this->setSettings($id, 'FeedsNodeProcessor', array('bundle' => 'article'));
}
/**
@@ -344,8 +347,13 @@ class FeedsWebTestCase extends DrupalWebTestCase {
// Check whether feed got properly added to scheduler.
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = :id AND id = 0 AND name = 'feeds_source_import' AND last <> 0 AND scheduled = 0", array(':id' => $id))->fetchField());
// There must be only one entry for callback 'expire' - no matter what the feed_nid is.
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = :id AND name = 'feeds_importer_expire' AND last <> 0 AND scheduled = 0", array(':id' => $id))->fetchField());
// Check expire scheduler.
if (feeds_importer($id)->processor->expiryTime() == FEEDS_EXPIRE_NEVER) {
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = :id AND id = 0 AND name = 'feeds_source_expire'", array(':id' => $id))->fetchField());
}
else {
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = :id AND id = 0 AND name = 'feeds_source_expire'", array(':id' => $id))->fetchField());
}
}
/**
@@ -377,6 +385,50 @@ class FeedsWebTestCase extends DrupalWebTestCase {
$this->assertEqual($config['processor']['plugin_key'], $processor, 'Correct processor');
}
/**
* Overrides DrupalWebTestCase::assertFieldByXPath().
*
* The core version has a bug, this is the D8 version.
*
* @todo Remove once https://drupal.org/node/2105617 lands.
*/
protected function assertFieldByXPath($xpath, $value = NULL, $message = '', $group = 'Other') {
$fields = $this->xpath($xpath);
// If value specified then check array for match.
$found = TRUE;
if (isset($value)) {
$found = FALSE;
if ($fields) {
foreach ($fields as $field) {
if (isset($field['value']) && $field['value'] == $value) {
// Input element with correct value.
$found = TRUE;
}
elseif (isset($field->option) || isset($field->optgroup)) {
// Select element found.
$selected = $this->getSelectedItem($field);
if ($selected === FALSE) {
// No item selected so use first item.
$items = $this->getAllOptions($field);
if (!empty($items) && $items[0]['value'] == $value) {
$found = TRUE;
}
}
elseif ($selected == $value) {
$found = TRUE;
}
}
elseif ((string) $field == $value) {
// Text area with correct text.
$found = TRUE;
}
}
}
}
return $this->assertTrue($fields && $found, $message, $group);
}
/**
* Adds mappings to a given configuration.
*
@@ -388,7 +440,7 @@ class FeedsWebTestCase extends DrupalWebTestCase {
* @param bool $test_mappings
* (optional) TRUE to automatically test mapping configs. Defaults to TRUE.
*/
public function addMappings($id, $mappings, $test_mappings = TRUE) {
public function addMappings($id, array $mappings, $test_mappings = TRUE) {
$path = "admin/structure/feeds/$id/mapping";
@@ -407,7 +459,7 @@ class FeedsWebTestCase extends DrupalWebTestCase {
$mapping = array('source' => $mapping['source'], 'target' => $mapping['target']);
// Add mapping.
$this->drupalPost($path, $mapping, t('Add'));
$this->drupalPost($path, $mapping, t('Save'));
// If there are other configuration options, set them.
if ($config) {
@@ -432,18 +484,18 @@ class FeedsWebTestCase extends DrupalWebTestCase {
/**
* Remove mappings from a given configuration.
*
* This function mimicks the Javascript behavior in feeds_ui.js
*
* @param string $id
* ID of the importer.
* @param array $mappings
* An array of mapping arrays. Each mapping array must have a source and
* a target key and can have a unique key.
* @param bool $test_mappings
* (optional) TRUE to automatically test mapping configs. Defaults to TRUE.
*/
public function removeMappings($id, $mappings, $test_mappings = TRUE) {
public function removeMappings($id, array $mappings, $test_mappings = TRUE) {
$path = "admin/structure/feeds/$id/mapping";
$current_mappings = $this->getCurrentMappings($id);
$edit = array();
// Iterate through all mappings and remove via the form.
foreach ($mappings as $i => $mapping) {
@@ -453,17 +505,11 @@ class FeedsWebTestCase extends DrupalWebTestCase {
$this->assertEqual($current_mapping_key, $i, 'Mapping exists before removal.');
}
$remove_mapping = array("remove_flags[$i]" => 1);
$this->drupalPost($path, $remove_mapping, t('Save'));
$this->assertText('Your changes have been saved.');
if ($test_mappings) {
$current_mapping_key = $this->mappingExists($id, $i, $mapping['source'], $mapping['target']);
$this->assertEqual($current_mapping_key, -1, 'Mapping does not exist after removal.');
}
$edit["remove_flags[$i]"] = 1;
}
$this->drupalPost($path, $edit, t('Save'));
$this->assertText('Your changes have been saved.');
}
/**

View File

@@ -1,3 +1,3 @@
"guid","title","created","alpha","beta","gamma","delta","body"
1,"Lorem ipsum",1251936720,"Lorem",42,"4.2",3.14159265,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat."
2,"Ut wisi enim ad minim veniam",1251932360,"Ut wisi",32,"1.2",5.62951413,"Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat."
"guid","title","created","alpha","beta","gamma","delta","epsilon","body"
1,"Lorem ipsum",1251936720,"Lorem",42,"4.2",3.14159265,1,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat."
2,"Ut wisi enim ad minim veniam",1251932360,"Ut wisi",32,"1.2",5.62951413,0,"Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat."
1 guid title created alpha beta gamma delta epsilon body
2 1 Lorem ipsum 1251936720 Lorem 42 4.2 3.14159265 1 Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
3 2 Ut wisi enim ad minim veniam 1251932360 Ut wisi 32 1.2 5.62951413 0 Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

View File

@@ -0,0 +1,3 @@
"guid","title","created","end"
1,"Lorem ipsum",1251936720,1351936720
2,"Ut wisi enim ad minim veniam",1251932360,1351932360
1 guid title created end
2 1 Lorem ipsum 1251936720 1351936720
3 2 Ut wisi enim ad minim veniam 1251932360 1351932360

View File

@@ -0,0 +1,3 @@
"guid","title","created","end","alpha","beta","gamma","delta","epsilon","body","link_title","url"
1,"Lorem ipsum",,,,,,,,,,
2,"Ut wisi enim ad minim veniam",0,0,"0",0,0,0,0,0,0,0
1 guid title created end alpha beta gamma delta epsilon body link_title url
2 1 Lorem ipsum
3 2 Ut wisi enim ad minim veniam 0 0 0 0 0 0 0 0 0 0

View File

@@ -0,0 +1,3 @@
"guid","title","created","alpha","beta","gamma","delta","body","language"
1,"Lorem ipsum",1251936720,"Lorem",42,"4.2",3.14159265,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.","nl"
2,"Ut wisi enim ad minim veniam",1251932360,"Ut wisi",32,"1.2",5.62951413,"Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat."
Can't render this file because it has a wrong number of fields in line 3.

View File

@@ -0,0 +1,3 @@
"guid","title","link_title","url"
1,"Lorem ipsum","Feeds","https://www.drupal.org/project/feeds"
2,"Ut wisi enim ad minim veniam","Framework for expected behavior when importing empty/blank values","https://www.drupal.org/node/1107522"
1 guid title link_title url
2 1 Lorem ipsum Feeds https://www.drupal.org/project/feeds
3 2 Ut wisi enim ad minim veniam Framework for expected behavior when importing empty/blank values https://www.drupal.org/node/1107522

View File

@@ -0,0 +1,3 @@
"guid","title"
1,"Lorem ipsum"
2,"Ut wisi enim ad minim veniam"
1 guid title
2 1 Lorem ipsum
3 2 Ut wisi enim ad minim veniam

View File

@@ -0,0 +1,263 @@
<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xml:base="http://developmentseed.org/blog/all" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Development Seed - Technological Solutions for Progressive Organizations</title>
<link>http://developmentseed.org/blog/all</link>
<description></description>
<language>en</language>
<item>
<title>Managing News Translation Workflow: Two Way Translation Updates</title>
<link>http://developmentseed.org/blog/2009/oct/06/open-atrium-translation-workflow-two-way-updating</link>
<description>&lt;div class=&quot;field field-type-text field-field-subtitle&quot;&gt;
&lt;div class=&quot;field-items&quot;&gt;
&lt;div class=&quot;field-item odd&quot;&gt;
&lt;p&gt;A new translation process for Open Atrium and integration with Localize Drupal&lt;/p&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#039;node-body&#039;&gt;&lt;p&gt;The &lt;a href=&quot;http://openatrium.com/&quot;&gt;Open Atrium&lt;/a&gt; &lt;a href=&quot;http://developmentseed.org/blog/2009/jul/16/open-atrium-solving-translation-puzzle&quot;&gt;translation infrastructure&lt;/a&gt; (and Drupal translations in general) are progressing quickly. For Open Atrium to be well translated we first need Drupal&#039;s modules to be translated, so I am splitting efforts at the moment between helping with &lt;a href=&quot;http://localize.drupal.org&quot;&gt;Localize Drupal&lt;/a&gt; and improving &lt;a href=&quot;https://translate.openatrium.com&quot;&gt;Open Atrium Translate&lt;/a&gt;. Already, it is much easier to automatically download your language, get updates from a translation server, protect locally translated strings, and scale the translation system so that translation servers can talk to each other.&lt;/p&gt;
&lt;h1&gt;Automatically download your language&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2496/3984689117_57559c74eb.jpg&quot; alt=&quot;Magical translation install&quot; /&gt;&lt;/p&gt;
&lt;p&gt;For more than a month now you have been able to install Open Atrium, select one of its 20+ languages, and have the translation automatically downloaded and installed on your site. While this has been working for awhile now, we are still refining the process. One change we&#039;ve already made is that now translations are downloaded in multiple smaller packages, rather than a single large one.&lt;/p&gt;
&lt;p&gt;Once your translation is installed, you can use tools like the &lt;a href=&quot;http://drupal.org/project/l10n_client&quot;&gt;Localization client&lt;/a&gt;, which comes bundled in the Open Atrium install, to translate page strings and then optionally contribute them back to the localization server, automatically. This flow of translations goes both ways, so your site gets the latest updates from the server just as you can send your latest updates to the server.&lt;/p&gt;
&lt;h1&gt;Two way translation updates&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;But what happens with my locally translated strings, which I like more than the ones that come out of the box, when I update from the server?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2442/3984689343_e9b7c32718.jpg&quot; alt=&quot;Two ways translation updates&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In a word, nothing. There has been a major improvement on this front. Now your translations are tracked and won&#039;t be overwritten by someone else&#039;s translations when you update, unless you choose for them to be. This means that you can contribute your translations, benefit from others contributing theirs, and make the world a better (translated) place, without loosing any custom work that you want. Let the translations flow!&lt;/p&gt;&lt;/div&gt;</description>
<comments>http://developmentseed.org/blog/2009/oct/06/open-atrium-translation-workflow-two-way-updating#comments</comments>
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
<category domain="http://developmentseed.org/tags/localization">localization</category>
<category domain="http://developmentseed.org/tags/localization-client">localization client</category>
<category domain="http://developmentseed.org/tags/localization-server">localization server</category>
<category domain="http://developmentseed.org/tags/open-atrium">open atrium</category>
<category domain="http://developmentseed.org/tags/translation">translation</category>
<category domain="http://developmentseed.org/tags/translation-server">translation server</category>
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
<pubDate>Tue, 06 Oct 2009 15:21:48 +0000</pubDate>
<dc:creator>Development Seed</dc:creator>
<guid isPermaLink="false">974 at http://developmentseed.org</guid>
</item>
<item>
<title>Week in DC Tech: October 5th Edition</title>
<link>http://developmentseed.org/blog/2009/oct/05/week-dc-tech-october-5th-edition</link>
<description>&lt;div class=&quot;field field-type-text field-field-subtitle&quot;&gt;
&lt;div class=&quot;field-items&quot;&gt;
&lt;div class=&quot;field-item odd&quot;&gt;
&lt;p&gt;Drupal, PHP, and Mapping This Week in Washington, DC&lt;/p&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#039;node-body&#039;&gt;&lt;p&gt;&lt;img src=&quot;http://developmentseed.org/sites/developmentseed.org/files/dctech2_0_0.png&quot; alt=&quot;Week in DC Tech&quot; /&gt;&lt;/p&gt;
&lt;p&gt;There are some great technology events happening this week in Washington, DC, so if you&#039;re looking to talk code, help map the city, or just hear about some neat projects and ideas, you&#039;re in luck. Below are the events that caught our eye, and you can find a full list of technology events happening this week at &lt;a href=&quot;http://www.dctechevents.com/&quot;&gt;DC Tech Events&lt;/a&gt;. Have a great week!&lt;/p&gt;
&lt;h1&gt;Wednesday, October 7&lt;/h1&gt;
&lt;p&gt;6:30 pm&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://drupal.meetup.com/21/calendar/11332695/&quot;&gt;&lt;strong&gt;NOVA Drupal Meetup&lt;/strong&gt;&lt;/a&gt;: Are you a Drupal developer, use a Drupal site, or just want to learn more about the open source content management system? Come out for this meetup to meet other Drupal fans and hear how people are using the CMS.&lt;/p&gt;
&lt;p&gt;6:30 pm&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://groups.google.com/group/washington-dcphp-group/browse_thread/thread/716d4a625287fef5?hl=en&quot;&gt;&lt;strong&gt;DC PHP Beverage Subgroup&lt;/strong&gt;&lt;/a&gt;: If you&#039;re looking to talk code with PHP developers who share your interest, come out for this casual meetup to chat over beers.&lt;/p&gt;
&lt;p&gt;7:00 pm&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://hacdc.org/&quot;&gt;&lt;strong&gt;Mapping DC Meeting&lt;/strong&gt;&lt;/a&gt;: Come out for this meetup if you want to help create high quality, free maps of Washington, DC. The &lt;a href=&quot;http://wiki.openstreetmap.org/wiki/MappingDC&quot;&gt;Mapping DC&lt;/a&gt; group is doing this, starting with creating a detailed map of the National Zoo.&lt;/p&gt;&lt;/div&gt;</description>
<comments>http://developmentseed.org/blog/2009/oct/05/week-dc-tech-october-5th-edition#comments</comments>
<category domain="http://developmentseed.org/tags/washington-dc">Washington DC</category>
<pubDate>Mon, 05 Oct 2009 15:27:40 +0000</pubDate>
<dc:creator>Development Seed</dc:creator>
<guid isPermaLink="false">973 at http://developmentseed.org</guid>
</item>
<item>
<title>Mapping Innovation at the World Bank with Open Atrium</title>
<link>http://developmentseed.org/blog/2009/oct/02/mapping-innovation-world-bank-open-atrium</link>
<description>&lt;div class=&quot;field field-type-text field-field-subtitle&quot;&gt;
&lt;div class=&quot;field-items&quot;&gt;
&lt;div class=&quot;field-item odd&quot;&gt;
&lt;p&gt;Using map and faceted search features to improve collaboration&lt;/p&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#039;node-body&#039;&gt;&lt;p&gt;&lt;a href=&quot;http://openatrium.com/&quot;&gt;Open Atrium&lt;/a&gt; is being used as a base platform for collaboration at the World Bank because of its feature flexibility. Last week the World Bank launched a new Open Atrium site called &quot;Innovate,&quot; which is being used to support an organization-wide initiative to better share information about successful projects and approaches to solving problems.&lt;/p&gt;
&lt;p&gt;The core of the site is built around helping World Bank staff discover relevant &quot;innovations&quot; happening around the world and providing a space to discuss them with colleagues in topical discussion groups. To facilitate this workflow we built a custom map-based browser feature that combines custom maps with faceted search, letting users quickly find interesting content. The screenshots below from a staging site with a partial database show what this feature looks like.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3419/3974644312_c992e1afe8.jpg&quot; alt=&quot;The map-based browser feature makes custom maps with faceted search&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As users apply new facets to their searches, the map results update to reveal global coverage for innovations that meet the search criteria.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2600/3974644162_a44cc3a89a.jpg&quot; alt=&quot;Add new facets to the search to further customize the map&quot; /&gt;&lt;/p&gt;&lt;/div&gt;</description>
<comments>http://developmentseed.org/blog/2009/oct/02/mapping-innovation-world-bank-open-atrium#comments</comments>
<category domain="http://developmentseed.org/tags/custom-mapping">custom mapping</category>
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
<category domain="http://developmentseed.org/tags/faceted-search">faceted search</category>
<category domain="http://developmentseed.org/tags/intranet">intranet</category>
<category domain="http://developmentseed.org/tags/map-basec-browser">map-basec browser</category>
<category domain="http://developmentseed.org/tags/mapbox">mapbox</category>
<category domain="http://developmentseed.org/tags/open-atrium">open atrium</category>
<category domain="http://developmentseed.org/tags/world-bank">World Bank</category>
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
<pubDate>Fri, 02 Oct 2009 14:31:04 +0000</pubDate>
<dc:creator>Development Seed</dc:creator>
<guid isPermaLink="false">972 at http://developmentseed.org</guid>
</item>
<item>
<title>September GeoDC Meetup Tonight</title>
<link>http://developmentseed.org/blog/2009/sep/30/september-geodc-meetup-tonight</link>
<description>&lt;div class=&quot;field field-type-text field-field-subtitle&quot;&gt;
&lt;div class=&quot;field-items&quot;&gt;
&lt;div class=&quot;field-item odd&quot;&gt;
&lt;p&gt;Presentations on Using Amazon&amp;#8217;s Web Services and OpenStreet Map and an iPhone App that Maps Government Data&lt;/p&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#039;node-body&#039;&gt;&lt;p&gt;Today is the last Wednesday of the month, which means it&#039;s time for another &lt;a href=&quot;http://geo-dc.ning.com/xn/detail/3537548:Event:1223?xg_source=activity&quot;&gt;GeoDC meetup&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3525/3966592859_f7f4cb179c.jpg&quot; alt=&quot;September GeoDC Meetup&quot; /&gt;&lt;/p&gt;
&lt;p&gt;There will be two short presentations at the meetup. &lt;a href=&quot;http://developmentseed.org/team/tom-macwright&quot;&gt;Tom MacWright&lt;/a&gt; from Development Seed will talk about how using Amazon&#039;s web services and &lt;a href=&quot;http://www.openstreetmap.org/&quot;&gt;OpenStreetMap&lt;/a&gt; has helped our mapping team design, render, and host custom maps. Brian Sobel of &lt;a href=&quot;http://www.innovationgeo.com/&quot;&gt;Innovation Geo&lt;/a&gt; will present &lt;a href=&quot;http://areyousafedc.com/&quot;&gt;Are You Safe&lt;/a&gt;, an iPhone App that uses open government data to give users up-to-date and hyper-local information about crime.&lt;/p&gt;
&lt;p&gt;The meetup will run from 7:00 to 9:00 pm at the offices of &lt;a href=&quot;http://www.fortiusone.com&quot;&gt;Fortius One&lt;/a&gt; at 2200 Wilson Blvd, Suite 307 in Arlington, just a &lt;a href=&quot;http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=2200+Wilson+Blvd+%23+307+Arlington,+VA+22201-3324&amp;amp;sll=38.893037,-77.072783&amp;amp;sspn=0.039481,0.087633&amp;amp;ie=UTF8&amp;amp;ll=38.8912,-77.086236&amp;amp;spn=0.009871,0.021908&amp;amp;t=h&amp;amp;z=16&amp;amp;iwloc=A&quot;&gt;short walk from the Courthouse metro stop on the orange line&lt;/a&gt;. Hope to see you there!&lt;/p&gt;&lt;/div&gt;</description>
<comments>http://developmentseed.org/blog/2009/sep/30/september-geodc-meetup-tonight#comments</comments>
<category domain="http://developmentseed.org/tags/geodc">GeoDC</category>
<category domain="http://developmentseed.org/tags/washington-dc">Washington DC</category>
<pubDate>Wed, 30 Sep 2009 12:02:53 +0000</pubDate>
<dc:creator>Development Seed</dc:creator>
<guid isPermaLink="false">971 at http://developmentseed.org</guid>
</item>
<item>
<title>Week in DC Tech: September 28th Edition</title>
<link>http://developmentseed.org/blog/2009/sep/28/week-dc-tech-september-28th-edition</link>
<description>&lt;div class=&quot;field field-type-text field-field-subtitle&quot;&gt;
&lt;div class=&quot;field-items&quot;&gt;
&lt;div class=&quot;field-item odd&quot;&gt;
&lt;p&gt;Healthcare 2.0, iPhone Development, Online Storytelling, and More This Week in Washington, DC&lt;/p&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#039;node-body&#039;&gt;&lt;p&gt;&lt;img src=&quot;http://developmentseed.org/sites/developmentseed.org/files/dctech2_0_0.png&quot; alt=&quot;Week in DC Tech&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Looking to geek out this week? There are a bunch of interesting technology events happening in Washington, DC this week, including a look at how social media is impacting healthcare, a screening of online clips from a journalist/filmmaker, and lightning talks on all kinds of geekery by the HacDC folks. Below are the events that caught our eye, and you can find a full list of what&#039;s happening this week in technology over at &lt;a href=&quot;http://www.dctechevents.com/&quot;&gt;DC Tech Events&lt;/a&gt;. Have a great week!&lt;/p&gt;
&lt;h1&gt;Tuesday, September 29&lt;/h1&gt;
&lt;p&gt;6:00 pm&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.meetup.com/DC-MD-VA-Health-2-0/calendar/11291017/&quot;&gt;&lt;strong&gt;Health 2.0 Meetup&lt;/strong&gt;&lt;/a&gt;: Curious as to how - and if - online technologies are impacting healthcare? At this meetup two speakers - Sanjay Koyani from the U.S. Food and Drug Administration and Taylor Walsh from MetroHealth Media - will talk about what they&#039;re seeing and implementing.&lt;/p&gt;
&lt;p&gt;7:00 pm&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://nscodernightdc.com/&quot;&gt;&lt;strong&gt;NSCoderNightDC&lt;/strong&gt;&lt;/a&gt;: Want to build an iphone app, or talk about one that you&#039;ve already built? Come out for this meetup to talk about mac and iphone development, share the latest news from Apple, and eat some delicious French desserts.&lt;/p&gt;&lt;/div&gt;</description>
<comments>http://developmentseed.org/blog/2009/sep/28/week-dc-tech-september-28th-edition#comments</comments>
<category domain="http://developmentseed.org/tags/washington-dc">Washington DC</category>
<pubDate>Mon, 28 Sep 2009 15:33:15 +0000</pubDate>
<dc:creator>Development Seed</dc:creator>
<guid isPermaLink="false">970 at http://developmentseed.org</guid>
</item>
<item>
<title>Open Data for Microfinance: The New MIXMarket.org</title>
<link>http://developmentseed.org/blog/2009/sep/24/open-data-microfinance-new-mixmarketorg</link>
<description>&lt;div class=&quot;field field-type-text field-field-subtitle&quot;&gt;
&lt;div class=&quot;field-items&quot;&gt;
&lt;div class=&quot;field-item odd&quot;&gt;
&lt;p&gt;Relaunch focuses on rich data visualization and downloadable data&lt;/p&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#039;node-body&#039;&gt;&lt;p&gt;The launch of the new &lt;a href=&quot;http://www.mixmarket.org/&quot;&gt;MIX Market&lt;/a&gt; is a big win for open data in international development, and it vastly improves how rich financial data sets can be accessed. The MIX Market is like a Bloomberg for microfinance, publishing data on more than 1,500 microfinance institutions (MFIs) in more than 190 countries and affecting 80,021,351 people. Additionally, each MFI has as many as 150 financial indicators and in some cases going back as far as 1995. The goal of this tool is simple - to open this information up to help MFIs, researchers, raters, evaluators, and governmental and regulatory agencies better see the marketplace, and that makes for better international development.&lt;/p&gt;
&lt;p&gt;There are profiles for every country that the MIX Market is hosting. Take a look at the country landing page for India, showing how India stacks up to other peer groups and listing out all MFIs, networks, and funders and service providers.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3517/3941870722_390f5aa65d.jpg&quot; alt=&quot;Country profiles give a quick overview of the performance of its microfinance institutions.&quot; /&gt;&lt;/p&gt;&lt;/div&gt;</description>
<comments>http://developmentseed.org/blog/2009/sep/24/open-data-microfinance-new-mixmarketorg#comments</comments>
<category domain="http://developmentseed.org/tags/data-visualization">data visualization</category>
<category domain="http://developmentseed.org/tags/graphs">graphs</category>
<category domain="http://developmentseed.org/tags/microfinance">microfinance</category>
<category domain="http://developmentseed.org/tags/mix-market">MIX Market</category>
<category domain="http://developmentseed.org/tags/open-data">open data</category>
<category domain="http://developmentseed.org/tags/salesforce">salesforce</category>
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
<pubDate>Thu, 24 Sep 2009 13:09:10 +0000</pubDate>
<dc:creator>Development Seed</dc:creator>
<guid isPermaLink="false">969 at http://developmentseed.org</guid>
</item>
<item>
<title>Integrating the Siteminder Access System in an Open Atrium-based Intranet</title>
<link>http://developmentseed.org/blog/2009/sep/22/integrating-siteminder-access-system-open-atrium-based-intranet</link>
<description>&lt;div class=&quot;field field-type-text field-field-subtitle&quot;&gt;
&lt;div class=&quot;field-items&quot;&gt;
&lt;div class=&quot;field-item odd&quot;&gt;
&lt;p&gt;Upgraded Siteminder Module in Drupal allows for better integration with Siteminder &lt;/p&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#039;node-body&#039;&gt;&lt;p&gt;In &lt;a href=&quot;http://developmentseed.org/blog/2009/sep/08/custom-open-atrium-intranet-launches-world-bank&quot;&gt;our recent work on the World Bank&#039;s Communicate intranet&lt;/a&gt;, we needed to integrate the &lt;a href=&quot;http://www.ca.com/us/internet-access-control.aspx&quot;&gt;Siteminder access system&lt;/a&gt; into the &lt;a href=&quot;http://openatrium.com/&quot;&gt;Open Atrium&lt;/a&gt;-based intranet &quot;Communicate&quot; to allow World Bank staff to use the same single sign-on credentials that they use to access all their internal web systems. To do this, we upgraded the Siteminder module for Drupal. You can download the &lt;a href=&quot;http://drupal.org/project/siteminder&quot;&gt;new module from its Drupal project page&lt;/a&gt; and &lt;a href=&quot;http://cvs.drupal.org/viewvc.py/drupal/contributions/modules/siteminder/README.txt?revision=1.2&amp;amp;view=markup&amp;amp;pathrev=DRUPAL-6--1-0-ALPHA1&quot;&gt;learn more about its API and how to write your own Siteminder plugin in its documentation&lt;/a&gt; and from reading the module&#039;s code. First, here is a little more background on the changes.&lt;/p&gt;
&lt;p&gt;The Siteminder system, from &lt;a href=&quot;http://www.ca.com/us/&quot;&gt;Computer Associates&lt;/a&gt;, is used by many enterprise-level organizations to authenticate signing on to their web resources. How it works is that you can designate a site - like an Open Atrium powered intranet - to be protected by the Siteminder system. Once a site is protected by Siteminder, all traffic to that site is routed through Siteminder first and then on to the actual site. Siteminder sets certain HTTP headers in the user&#039;s request, and Drupal can then examine them to determine credentials. What the Drupal Siteminder module does is map the Siteminder header values to Drupal users and allow a user to login based on the headers they send.&lt;/p&gt;
&lt;p&gt;In addition to authentication, the Siteminder system also stores other information about users. When the Siteminder system sends HTTP headers for authentication, it can also send information about a user - like her name, email address, phone number, and so on. We wanted to be able to pull this information into the intranet too. To achieve this, we re-wrote the Siteminder module in such a way that it&#039;s easy to write a plugin module to provide the fields to which you&#039;d like to map this extra Siteminder meta information and to determine how this information is processed and saved. To do this for the World Bank&#039;s intranet, we built the Siteminder Profile module, which lets you pick a CCK node type to serve as the target content profile for a user as well as select a few taxonomy vocabularies. Then by using the main module&#039;s administrative interface, you can choose which Siteminder headers should get mapped to which CCK fields and vocabularies based on the designated node type and vocabularies you selected in the Siteminder Profile settings page.&lt;/p&gt;
&lt;p&gt;But what happens if a person&#039;s information changes in the Siteminder database - for example if they change phone numbers or office buildings? The Siteminder module now has built-in capability and an API to check whether values in users&#039; profiles have changed in the Siteminder system. The Siteminder Profile module uses this API and saves a new version of a user&#039;s profile if it detects that a value has changed in the Siteminder system database.&lt;/p&gt;&lt;/div&gt;</description>
<comments>http://developmentseed.org/blog/2009/sep/22/integrating-siteminder-access-system-open-atrium-based-intranet#comments</comments>
<category domain="http://developmentseed.org/tags/authentication">authentication</category>
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
<category domain="http://developmentseed.org/tags/open-atrium">open atrium</category>
<category domain="http://developmentseed.org/tags/siteminder">siteminder</category>
<category domain="http://developmentseed.org/tags/siteminder-module">siteminder module</category>
<category domain="http://developmentseed.org/channel/drupal-planet">Drupal planet</category>
<pubDate>Tue, 22 Sep 2009 18:02:21 +0000</pubDate>
<dc:creator>Development Seed</dc:creator>
<guid isPermaLink="false">964 at http://developmentseed.org</guid>
</item>
<item>
<title>Week in DC Tech: September 21 Edition</title>
<link>http://developmentseed.org/blog/2009/sep/21/week-dc-tech-september-21-edition</link>
<description>&lt;div class=&quot;field field-type-text field-field-subtitle&quot;&gt;
&lt;div class=&quot;field-items&quot;&gt;
&lt;div class=&quot;field-item odd&quot;&gt;
&lt;p&gt;PHP, Design, Twitter, and Wikipedia This Week in Washington, DC&lt;/p&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#039;node-body&#039;&gt;&lt;p&gt;&lt;img src=&quot;http://developmentseed.org/sites/default/files/dctech2_0.png&quot; alt=&quot;Week in DC Tech&quot; /&gt;&lt;/p&gt;
&lt;p&gt;There&#039;s an interesting variety of technology events happening in Washington, DC this week with focuses ranging from using Twitter for advocacy to drinking beers with php developers to discussing designing way outside of the box. Additionally tomorrow is international Car Free Day and there are events happening throughout the city to celebrate it and help you how to rely on cars less. Below are the events that caught our eye, and you can find a full list of the week&#039;s technology events at &lt;a href=&quot;http://www.dctechevents.com/&quot;&gt;DC Tech Events&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Tuesday, September 22&lt;/h2&gt;
&lt;p&gt;All day&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.carfreemetrodc.com/&quot;&gt;&lt;strong&gt;Car Free Day&lt;/strong&gt;&lt;/a&gt;: Help reduce traffic and improve air quality by leaving your car at home on Tuesday in celebration of Car Free Day. There are also &lt;a href=&quot;http://www.carfreemetrodc.com/Information/tabid/57/Default.aspx&quot;&gt;free bike repair trainings, yoga classes, and other events&lt;/a&gt; happening throughout the day to help you lead a car free lifestyle.&lt;/p&gt;
&lt;p&gt;6:00 - 8:00 pm&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.php.net/cal.php?id=3075&quot;&gt;&lt;strong&gt;DC PHP Beverage Subgroup&lt;/strong&gt;&lt;/a&gt;: Come out to talk code with other php developers over a few beers. This is a great opportunity to get to know local php developers in a casual setting while sharing stories about your code.&lt;/p&gt;&lt;/div&gt;</description>
<comments>http://developmentseed.org/blog/2009/sep/21/week-dc-tech-september-21-edition#comments</comments>
<category domain="http://developmentseed.org/tags/washington-dc">Washington DC</category>
<pubDate>Mon, 21 Sep 2009 16:03:24 +0000</pubDate>
<dc:creator>Development Seed</dc:creator>
<guid isPermaLink="false">968 at http://developmentseed.org</guid>
</item>
<item>
<title>Peru&#039;s Software Freedom Day: Impressions and Photos</title>
<link>http://developmentseed.org/blog/2009/sep/21/perus-software-freedom-day-impressions-and-photos</link>
<description>&lt;div class=&#039;node-body&#039;&gt;&lt;p&gt;There was a great turn out a &lt;a href=&quot;http://www.sfdperu.org/&quot;&gt;Software Freedom Day&lt;/a&gt; this weekend with 400 people in attendance and a solid 30 presentations. The &lt;a href=&quot;http://developmentseed.org/blog/2009/sep/15/preparing-perus-software-freedom-day-talks-drupal-features-and-open-atrium&quot;&gt;presentations in the Drupal track&lt;/a&gt; were some of the best attended sessions of the day. To get a sense of Drupal&#039;s traction down here, &quot;Drupal&quot; was mentioned in many sessions and conversations throughout the day, and not just by the people working directly with Drupal.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2653/3940335249_57ce995a84.jpg&quot; alt=&quot;Presenting on Features in Drupal and Managing News&quot; /&gt;
&lt;em&gt;Presenting on Features in Drupal and Managing News&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I had a great time meeting people and learning about the work being done in the different open source communities here in Peru. Software Freedom Day is becoming an annual event in Peru, and there were many discussions on improving the event for next year as well as keeping the energy going to improve the image of open source software in the country. It&#039;s great to see the community looking forward like this, and I&#039;m excited to help keep the open source movement growing in Peru.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/developmentseed/sets/72157622423999830/&quot;&gt;More photos from the event here.&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;</description>
<comments>http://developmentseed.org/blog/2009/sep/21/perus-software-freedom-day-impressions-and-photos#comments</comments>
<category domain="http://developmentseed.org/tags/drupal">Drupal</category>
<category domain="http://developmentseed.org/tags/open-source">open source</category>
<category domain="http://developmentseed.org/tags/peru">Peru</category>
<category domain="http://developmentseed.org/tags/software-freedom-day">software freedom day</category>
<pubDate>Mon, 21 Sep 2009 14:22:35 +0000</pubDate>
<dc:creator>Development Seed</dc:creator>
<guid isPermaLink="false">967 at http://developmentseed.org</guid>
</item>
</channel>
</rss>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:georss="http://www.georss.org/georss">
<updated>2010-09-07T21:45:39Z</updated>
<title>USGS M2.5+ Earthquakes</title>
<subtitle>Real-time, worldwide earthquake list for the past day</subtitle>
<link rel="self" href="http://earthquake.usgs.gov/earthquakes/catalogs/1day-M2.5.xml"/>
<link href="http://earthquake.usgs.gov/earthquakes/"/>
<id>http://earthquake.usgs.gov/</id>
<icon>/favicon.ico</icon>
<entry><id>urn:earthquake-usgs-gov:ak:10076864</id><title>M 2.6, Central Alaska</title><updated>2010-09-07T21:08:45Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076864.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/65_-150.jpg" alt="64.858&#176;N 150.864&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 21:08:45 UTC<br>Tuesday, September 7, 2010 01:08:45 PM at epicenter</p><p><strong>Depth</strong>: 11.20 km (6.96 mi)</p>]]></summary><georss:point>64.8581 -150.8643</georss:point><georss:elev>-11200</georss:elev><category label="Age" term="Past hour"/></entry>
<entry><id>urn:earthquake-usgs-gov:us:2010axbz</id><title>M 4.9, southern Qinghai, China</title><updated>2010-09-07T20:51:02Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axbz.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/35_95.jpg" alt="33.329&#176;N 96.332&#176;E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 20:51:02 UTC<br>Wednesday, September 8, 2010 04:51:02 AM at epicenter</p><p><strong>Depth</strong>: 47.50 km (29.52 mi)</p>]]></summary><georss:point>33.3289 96.3324</georss:point><georss:elev>-47500</georss:elev><category label="Age" term="Past hour"/></entry>
<entry><id>urn:earthquake-usgs-gov:us:2010axbr</id><title>M 5.2, southern East Pacific Rise</title><updated>2010-09-07T19:54:29Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axbr.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/us2010axbr" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-55_-120.jpg" alt="53.198&#176;S 118.068&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 19:54:29 UTC<br>Tuesday, September 7, 2010 11:54:29 AM at epicenter</p><p><strong>Depth</strong>: 15.50 km (9.63 mi)</p>]]></summary><georss:point>-53.1979 -118.0676</georss:point><georss:elev>-15500</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:us:2010axbp</id><title>M 5.0, South Island of New Zealand</title><updated>2010-09-07T19:49:57Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axbp.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-45_175.jpg" alt="43.437&#176;S 172.590&#176;E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 19:49:57 UTC<br>Wednesday, September 8, 2010 07:49:57 AM at epicenter</p><p><strong>Depth</strong>: 1.00 km (0.62 mi)</p>]]></summary><georss:point>-43.4371 172.5902</georss:point><georss:elev>-1000</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:ak:10076859</id><title>M 3.1, Andreanof Islands, Aleutian Islands, Alaska</title><updated>2010-09-07T19:20:05Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076859.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/ak10076859" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/50_-175.jpg" alt="51.526&#176;N 175.798&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 19:20:05 UTC<br>Tuesday, September 7, 2010 10:20:05 AM at epicenter</p><p><strong>Depth</strong>: 22.20 km (13.79 mi)</p>]]></summary><georss:point>51.5259 -175.7979</georss:point><georss:elev>-22200</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:ci:10793957</id><title>M 2.7, Southern California</title><updated>2010-09-07T18:50:42Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ci10793957.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/35_-115.jpg" alt="35.717&#176;N 116.960&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 18:50:42 UTC<br>Tuesday, September 7, 2010 11:50:42 AM at epicenter</p><p><strong>Depth</strong>: 7.80 km (4.85 mi)</p>]]></summary><georss:point>35.7170 -116.9597</georss:point><georss:elev>-7800</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:ci:10793909</id><title>M 3.5, Southern California</title><updated>2010-09-07T17:29:13Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ci10793909.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/ci10793909" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/35_-115.jpg" alt="35.727&#176;N 116.957&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 17:29:13 UTC<br>Tuesday, September 7, 2010 10:29:13 AM at epicenter</p><p><strong>Depth</strong>: 4.50 km (2.80 mi)</p>]]></summary><georss:point>35.7273 -116.9567</georss:point><georss:elev>-4500</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:ak:10076853</id><title>M 3.1, Andreanof Islands, Aleutian Islands, Alaska</title><updated>2010-09-07T17:08:19Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076853.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/ak10076853" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/50_-175.jpg" alt="51.090&#176;N 176.131&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 17:08:19 UTC<br>Tuesday, September 7, 2010 08:08:19 AM at epicenter</p><p><strong>Depth</strong>: 16.50 km (10.25 mi)</p>]]></summary><georss:point>51.0899 -176.1314</georss:point><georss:elev>-16500</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:us:2010axa9</id><title>M 6.3, Fiji region</title><updated>2010-09-07T16:13:32Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axa9.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-15_-180.jpg" alt="15.869&#176;S 179.261&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 16:13:32 UTC<br>Wednesday, September 8, 2010 04:13:32 AM at epicenter</p><p><strong>Depth</strong>: 10.00 km (6.21 mi)</p>]]></summary><georss:point>-15.8694 -179.2611</georss:point><georss:elev>-10000</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:us:2010axa7</id><title>M 5.3, Kyrgyzstan</title><updated>2010-09-07T15:41:42Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axa7.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/us2010axa7" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/40_75.jpg" alt="39.476&#176;N 73.825&#176;E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 15:41:42 UTC<br>Tuesday, September 7, 2010 09:41:42 PM at epicenter</p><p><strong>Depth</strong>: 39.70 km (24.67 mi)</p>]]></summary><georss:point>39.4759 73.8254</georss:point><georss:elev>-39700</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:ci:10793837</id><title>M 2.7, Southern California</title><updated>2010-09-07T13:07:21Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ci10793837.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/35_-115.jpg" alt="35.725&#176;N 116.963&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 13:07:21 UTC<br>Tuesday, September 7, 2010 06:07:21 AM at epicenter</p><p><strong>Depth</strong>: 3.60 km (2.24 mi)</p>]]></summary><georss:point>35.7245 -116.9630</georss:point><georss:elev>-3600</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:nc:71451855</id><title>M 2.5, Northern California</title><updated>2010-09-07T13:06:56Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/nc71451855.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/nc71451855" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/40_-120.jpg" alt="39.210&#176;N 120.067&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 13:06:56 UTC<br>Tuesday, September 7, 2010 06:06:56 AM at epicenter</p><p><strong>Depth</strong>: 8.20 km (5.10 mi)</p>]]></summary><georss:point>39.2102 -120.0667</georss:point><georss:elev>-8200</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:us:2010axax</id><title>M 5.4, Fiji region</title><updated>2010-09-07T12:49:01Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axax.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/us2010axax" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-15_-175.jpg" alt="14.361&#176;S 176.241&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 12:49:01 UTC<br>Wednesday, September 8, 2010 12:49:01 AM at epicenter</p><p><strong>Depth</strong>: 35.50 km (22.06 mi)</p>]]></summary><georss:point>-14.3605 -176.2406</georss:point><georss:elev>-35500</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:us:2010axat</id><title>M 5.0, Kuril Islands</title><updated>2010-09-07T11:30:52Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axat.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/us2010axat" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/45_150.jpg" alt="45.858&#176;N 151.311&#176;E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 11:30:52 UTC<br>Tuesday, September 7, 2010 11:30:52 PM at epicenter</p><p><strong>Depth</strong>: 30.30 km (18.83 mi)</p>]]></summary><georss:point>45.8582 151.3105</georss:point><georss:elev>-30300</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:mb:25757</id><title>M 2.7, western Montana</title><updated>2010-09-07T10:08:26Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/mb25757.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/45_-110.jpg" alt="44.951&#176;N 111.742&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 10:08:26 UTC<br>Tuesday, September 7, 2010 04:08:26 AM at epicenter</p><p><strong>Depth</strong>: 5.70 km (3.54 mi)</p>]]></summary><georss:point>44.9508 -111.7423</georss:point><georss:elev>-5700</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:ak:10076821</id><title>M 2.7, Andreanof Islands, Aleutian Islands, Alaska</title><updated>2010-09-07T08:40:35Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076821.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/ak10076821" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/50_-175.jpg" alt="51.201&#176;N 176.194&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 08:40:35 UTC<br>Monday, September 6, 2010 11:40:35 PM at epicenter</p><p><strong>Depth</strong>: 20.10 km (12.49 mi)</p>]]></summary><georss:point>51.2010 -176.1935</georss:point><georss:elev>-20100</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:us:2010axas</id><title>M 4.9, southwest of Sumatra, Indonesia</title><updated>2010-09-07T07:22:13Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axas.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-5_105.jpg" alt="7.128&#176;S 103.263&#176;E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 07:22:13 UTC<br>Tuesday, September 7, 2010 02:22:13 PM at epicenter</p><p><strong>Depth</strong>: 35.00 km (21.75 mi)</p>]]></summary><georss:point>-7.1275 103.2631</georss:point><georss:elev>-35000</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:nc:71451750</id><title>M 3.1, Central California</title><updated>2010-09-07T06:59:25Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/nc71451750.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/nc71451750" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/35_-120.jpg" alt="36.561&#176;N 121.068&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 06:59:25 UTC<br>Monday, September 6, 2010 11:59:25 PM at epicenter</p><p><strong>Depth</strong>: 8.40 km (5.22 mi)</p>]]></summary><georss:point>36.5605 -121.0677</georss:point><georss:elev>-8400</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:ak:10076797</id><title>M 4.2, Kodiak Island region, Alaska</title><updated>2010-09-07T05:54:04Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076797.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/ak10076797" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/55_-150.jpg" alt="56.980&#176;N 151.666&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 05:54:04 UTC<br>Monday, September 6, 2010 09:54:04 PM at epicenter</p><p><strong>Depth</strong>: 25.00 km (15.53 mi)</p>]]></summary><georss:point>56.9797 -151.6661</georss:point><georss:elev>-25000</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:ak:10076786</id><title>M 3.4, Andreanof Islands, Aleutian Islands, Alaska</title><updated>2010-09-07T04:43:36Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076786.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/ak10076786" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/50_-175.jpg" alt="51.098&#176;N 176.164&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 04:43:36 UTC<br>Monday, September 6, 2010 07:43:36 PM at epicenter</p><p><strong>Depth</strong>: 16.90 km (10.50 mi)</p>]]></summary><georss:point>51.0975 -176.1635</georss:point><georss:elev>-16900</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:ak:10076776</id><title>M 3.6, Andreanof Islands, Aleutian Islands, Alaska</title><updated>2010-09-07T03:43:43Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/ak10076776.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/50_-175.jpg" alt="51.471&#176;N 176.667&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 03:43:43 UTC<br>Monday, September 6, 2010 06:43:43 PM at epicenter</p><p><strong>Depth</strong>: 39.00 km (24.23 mi)</p>]]></summary><georss:point>51.4706 -176.6674</georss:point><georss:elev>-39000</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:us:2010axaf</id><title>M 5.3, southern Iran</title><updated>2010-09-07T02:11:07Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axaf.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/us2010axaf" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/25_55.jpg" alt="27.147&#176;N 54.588&#176;E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 02:11:07 UTC<br>Tuesday, September 7, 2010 05:41:07 AM at epicenter</p><p><strong>Depth</strong>: 27.90 km (17.34 mi)</p>]]></summary><georss:point>27.1465 54.5877</georss:point><georss:elev>-27900</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:us:2010axad</id><title>M 4.9, Fiji region</title><updated>2010-09-07T01:42:39Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axad.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-20_-180.jpg" alt="19.657&#176;S 177.699&#176;W" align="left" hspace="20" /><p>Tuesday, September 7, 2010 01:42:39 UTC<br>Tuesday, September 7, 2010 01:42:39 PM at epicenter</p><p><strong>Depth</strong>: 390.40 km (242.58 mi)</p>]]></summary><georss:point>-19.6573 -177.6987</georss:point><georss:elev>-390400</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:us:2010axab</id><title>M 5.8, southwest of Sumatra, Indonesia</title><updated>2010-09-07T00:57:26Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010axab.php"/><link rel="related" type="application/cap+xml" href="http://earthquake.usgs.gov/earthquakes/catalogs/cap/us2010axab" /><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-5_105.jpg" alt="6.967&#176;S 103.657&#176;E" align="left" hspace="20" /><p>Tuesday, September 7, 2010 00:57:26 UTC<br>Tuesday, September 7, 2010 07:57:26 AM at epicenter</p><p><strong>Depth</strong>: 34.10 km (21.19 mi)</p>]]></summary><georss:point>-6.9665 103.6573</georss:point><georss:elev>-34100</georss:elev><category label="Age" term="Past day"/></entry>
<entry><id>urn:earthquake-usgs-gov:us:2010awby</id><title>M 5.2, North Island of New Zealand</title><updated>2010-09-06T22:48:33Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/recenteqsww/Quakes/us2010awby.php"/><summary type="html"><![CDATA[<img src="http://earthquake.usgs.gov/images/globes/-40_175.jpg" alt="40.143&#176;S 176.657&#176;E" align="left" hspace="20" /><p>Monday, September 6, 2010 22:48:33 UTC<br>Tuesday, September 7, 2010 10:48:33 AM at epicenter</p><p><strong>Depth</strong>: 16.70 km (10.38 mi)</p>]]></summary><georss:point>-40.1430 176.6567</georss:point><georss:elev>-16700</georss:elev><category label="Age" term="Past day"/></entry>
</feed>

View File

@@ -0,0 +1,33 @@
<?php
/**
* @file
* Result of encoding_{code}.csv file parsed by ParserCSV.inc
*/
// JSON is used here because it supports unicode literals. PHP does not.
$json = <<<EOT
[
[
"id",
"text"
],
[
"1",
"\u672c\u65e5\u306f\u3044\u3044\u5929\u6c17"
],
[
"2",
"\uff71\uff72\uff73\uff74\uff75"
],
[
"3",
"\u30c6\u30b9\u30c8"
],
[
"4",
"\u2605"
]
]
EOT;
$control_result = json_decode($json);

View File

@@ -0,0 +1,5 @@
id,text
1,<EFBFBD>{<7B><><EFBFBD>͂<EFBFBD><CD82><EFBFBD><EFBFBD>V<EFBFBD>C
2,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
3,<EFBFBD>e<EFBFBD>X<EFBFBD>g
4,<EFBFBD><EFBFBD>
1 id text
2 1 本日はいい天気
3 2 アイウエオ
4 3 テスト
5 4

View File

@@ -0,0 +1,5 @@
id,text
1,<EFBFBD>{<7B><><EFBFBD>͂<EFBFBD><CD82><EFBFBD><EFBFBD>V<EFBFBD>C
2,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
3,<EFBFBD>e<EFBFBD>X<EFBFBD>g
4,<EFBFBD><EFBFBD>
1 id text
2 1 本日はいい天気
3 2 アイウエオ
4 3 テスト
5 4

View File

@@ -0,0 +1,5 @@
id,text
1,本日はいい天気
2,アイウエオ
3,テスト
4,
1 id text
2 1 本日はいい天気
3 2 アイウエオ
4 3 テスト
5 4

View File

@@ -0,0 +1,6 @@
Title,published,file,GUID,alt,title2
"Tubing is awesome",205200720,<?php print $files[0]; ?>,0,,
"Jeff vs Tom",428112720,<?php print $files[1]; ?>,1,,
"Attersee",1151766000,<?php print $files[2]; ?>,2,,
"H Street NE",1256326995,<?php print $files[3]; ?>,3,,
"La Fayette Park",1256326995,<?php print $files[4]; ?>,4,,

View File

@@ -1,6 +1,6 @@
Title,published,file,GUID
"Tubing is awesome",205200720,<?php print $files[0]; ?>,0
"Jeff vs Tom",428112720,<?php print $files[1]; ?>,1
"Attersee",1151766000,<?php print $files[2]; ?>,2
"H Street NE",1256326995,<?php print $files[3]; ?>,3
"La Fayette Park",1256326995,<?php print $files[4]; ?>,4
Title,published,file,GUID,alt,title2
"Tubing is awesome",205200720,<?php print $files[0]; ?>,0,Alt text 0,Title text 0
"Jeff vs Tom",428112720,<?php print $files[1]; ?>,1,Alt text 1,Title text 1
"Attersee",1151766000,<?php print $files[2]; ?>,2,Alt text 2,Title text 2
"H Street NE",1256326995,<?php print $files[3]; ?>,3,Alt text 3,Title text 3
"La Fayette Park",1256326995,<?php print $files[4]; ?>,4,Alt text 4,Title text 4

View File

@@ -0,0 +1,87 @@
Title,Body,published,GUID
"Ut wisi enim ad minim veniam", "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.",205200720,1
"Duis autem vel eum iriure dolor", "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.",428112720,2
"Nam liber tempor", "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.",1151766000,3
Typi non habent"", "Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem.",1256326995,4
"Lorem ipsum","Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.",1251936720,5
"Investigationes demonstraverunt", "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.",946702800,6
"Claritas est etiam", "Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum.",438112720,7
"Mirum est notare", "Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima.",1151066000,8
"Eodem modo typi", "Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.",1212891020,9
"Ut quam dolor", "Ut quam dolor, aliquam pretium elementum ac, auctor eu tortor.",1200837000,10
"Sed id dignissim lorem", "Donec nec urna mauris. Duis tincidunt",1201000000,11
"Aliquam feugiat diam", "Aliquam feugiat diam ac enim egestas ut cursus lacus fermentum.",1210922021,12
"Proin et fringilla leo", "Maecenas rhoncus velit quis nibh convallis pharetra.",1201832100,13
"Suspendisse potenti", "Integer commodo elit et arcu dapibus at hendrerit nunc dapibus.",1122838020,14
"Nunc eu lectus nisi", "Nunc eu lectus nisi, sed vestibulum mauris. Sed tincidunt vehicula sem, eu tincidunt massa ultrices vel.",1200827015,15
"Mauris tellus erat", "",1201845210,16
"Pellentesque porttitor gravida magna", "Pellentesque porttitor gravida magna, ut lacinia risus suscipit a. Nunc molestie molestie massa non auctor.",1211835320,17
"Pellentesque facilisis ultrices", "Pellentesque facilisis ultrices risus non porttitor. Donec dapibus velit in metus consectetur et ullamcorper velit volutpat.",1190835120,18
"Sed eros lectus", "Sed eros lectus, mollis vel commodo et, molestie vel urna.",1151825020,19
"Morbi consectetur fringilla dolor", "Morbi consectetur fringilla dolor. Morbi eleifend pharetra purus, non facilisis tortor ullamcorper sed.",1201745220,20
"Vivamus vitae lectus", "Vivamus vitae lectus ac urna tempus dapibus eu consectetur massa. Donec vitae arcu lectus, non ornare nunc. ",1201825020,21
"Fusce est felis", "Fusce est felis, tincidunt eu congue id, placerat nec massa.",1201836001,22
"Duis tristique velit", "Duis tristique velit vitae lacus malesuada sed commodo quam commodo.",1201832024,23
"In ac felis neque", "Integer dictum sapien eget nunc commodo convallis.",1201830020,24
"Proin a mi nulla", "Proin a mi nulla, sodales mattis nunc.",1201822020,25
"Pellentesque vitae massa", "Pellentesque vitae massa elementum augue varius suscipit at quis turpis.",1201810020,26
"Proin dapibus", "Nam pulvinar urna vel eros aliquam hendrerit.",1201636020,27
"Donec", "Nulla pulvinar felis nec nulla pretium id pulvinar risus scelerisque.",1201336020,28
"Quisque dictum sagittis purus", "Quisque dictum sagittis purus, nec tristique magna sagittis nec. Mauris tortor nisl, cursus sit amet varius vitae, posuere in ipsum.",1201236020,29
"Praesent", "Praesent tincidunt vulputate turpis non faucibus",1201132020,30
"Vestibulum", "Vestibulum volutpat interdum elit, quis aliquam leo lobortis non.",1201036020,31
"Aliquam", "Aliquam fringilla lobortis mollis.",1201022020,32
"Etiam faucibus", "Etiam faucibus, quam vitae sollicitudin sagittis, nisl metus ultricies risus, sed convallis nibh risus ut libero.",1201021020,33
"In hac habitasse", "Proin justo sapien, dapibus vel dictum non, vestibulum in neque.",1201010020,34
"Mauris risus dolor", "Maecenas rutrum diam suscipit mi feugiat venenatis.",1201005011,35
"Pellentesque habitant", "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.",1201001010,36
"Duis convallis", "Duis convallis quam non eros suscipit iaculis. Aliquam erat volutpat.",1201000010,37
"Proin adipiscing mi vel", "Proin nibh est, gravida ac condimentum viverra, hendrerit sodales tellus.",1200901010,38
"Nullam sodales", "Nullam sodales laoreet suscipit.",1200851010,39
"Duis ornare pulvinar purus", "Duis ornare pulvinar purus, at pulvinar nulla hendrerit vel.",1200801010,40
"Mauris sit amet nibh risus", "Mauris sit amet nibh risus, eget eleifend ante. Donec imperdiet ante quis ligula condimentum consectetur.",1200761010,41
"Fusce sit amet mi vitae", "Fusce sit amet mi vitae ipsum tempor rhoncus. Aenean sit amet diam erat, fringilla porttitor felis.",1200751010,42
"Cras blandit ornare", "Cras blandit ornare augue in tempor. Curabitur vitae dolor nibh, sed molestie metus.",1200601010,43
"Proin at eros", "Proin at eros ut est laoreet tristique. Duis ullamcorper, nisi eu gravida mattis, nibh ligula laoreet lectus, vitae elementum augue sem non nisl.",1200451010,44
"Vivamus sem purus", "Vivamus sem purus, viverra eget faucibus et, imperdiet vel massa.",1200551010,45
"Ut id nisl", "Morbi suscipit tincidunt ultrices. Suspendisse ornare aliquet elit ac accumsan.",1200121010,46
"Sed libero leo", "Phasellus ut sem sit amet justo sagittis placerat.",1200202010,47
"Quisque eros nunc", "Quisque eros nunc, iaculis id bibendum ut, imperdiet ut sem. Donec mi quam, ultricies sit amet ornare et, lacinia non libero.",1201222010,48
"Vestibulum vulputate", "Vestibulum vulputate, lacus quis fringilla imperdiet, nisi mi consequat lacus, eu sodales nisl nisi venenatis lacus.",1200022010,49
"Suspendisse sed", "Suspendisse sed est eget quam imperdiet laoreet.",1202200010,50
"Duis a lacus odio", "Duis a lacus odio. Nam luctus sapien id leo vestibulum tristique. Cras eu nisi velit, a aliquet turpis. Maecenas ligula est, ullamcorper vel placerat sit amet, scelerisque et lectus. Nunc velit massa; scelerisque et pretium non, sollicitudin vel tellus? Donec leo turpis, tempus dignissim placerat vel, venenatis a augue. Etiam condimentum porttitor urna, quis scelerisque justo pulvinar eget. Fusce nec nibh non enim mattis posuere. Cras pulvinar erat eget ante gravida congue. Pellentesque ultrices metus ut nunc suscipit id imperdiet nunc ornare. Nam consectetur erat quis massa congue vehicula eget vestibulum turpis. Morbi ac eleifend felis.",1202200010,51
"Vivamus tempor", "Vivamus tempor, mi a pulvinar convallis, massa enim pulvinar metus, nec fringilla quam ante eu erat. Cras dignissim, felis non euismod iaculis, est massa posuere diam, et auctor libero ipsum ac ipsum? Nullam iaculis, eros ac sodales sollicitudin; tellus ligula volutpat urna, eget mattis felis metus ac augue.",1202200010,52
"Sed molestie", "Sed molestie dolor sit amet neque dictum egestas? Aliquam vitae dui mi. Phasellus fermentum volutpat augue, quis ornare tortor facilisis ac. Suspendisse potenti. Duis facilisis massa at elit pharetra sit amet condimentum est pharetra.",1202200010,53
"Donec ut", "Donec ut est ipsum. Pellentesque porttitor eleifend neque non malesuada. Morbi sollicitudin varius dapibus. Morbi sit amet risus leo, eu suscipit urna. Suspendisse velit ligula, suscipit ac rhoncus eu, convallis in eros",1202100010,54
"Duis ut dolor sem", "Duis ut dolor sem. Donec convallis, nunc quis pulvinar tempus, leo est blandit lacus, et elementum lectus nisl et purus. Mauris eros eros, iaculis volutpat pretium euismod, porta id arcu. Integer tellus lacus, imperdiet sed vulputate varius, dignissim vel nisi. In porta molestie fermentum.",1202222101,55
"Fusce sodales luctus porta", "Fusce sodales luctus porta. Curabitur pellentesque tincidunt tristique. In hac habitasse platea dictumst.",1202123211,56
"In egestas lectus a sapien", "In egestas lectus a sapien sollicitudin nec blandit metus scelerisque. Proin et tortor eget risus congue sollicitudin. In auctor interdum turpis porta commodo. Donec faucibus elementum nibh, a egestas nisi tincidunt id.",1202232323,57
"Aliquam semper", "Aliquam semper egestas aliquet. Aliquam tristique velit sit amet leo sodales aliquam. Praesent cursus ipsum quis odio aliquet eu eleifend velit aliquam? Maecenas consequat lobortis augue, at venenatis enim hendrerit quis.",1202242452,58
"Curabitur tortor", "Curabitur tortor turpis, commodo eu pretium ac, sollicitudin a augue. ",1201341344,59
"Duis venenatis", "Duis venenatis lorem vel sapien suscipit consectetur. In vel lectus neque, ut rutrum sapien.",1204564533,60
"Phasellus ipsum metus", "Phasellus ipsum metus; suscipit nec malesuada et, fermentum eu nulla. Vivamus id libero in ligula gravida tristique at sed nibh. Cras congue, risus posuere hendrerit pharetra, ante justo eleifend sem, vitae faucibus lacus neque rhoncus urna.",1123452333,61
"Nullam porta", "Nullam porta, nisl eu ornare rhoncus, dolor tortor scelerisque justo, non placerat mauris purus vel mauris.",1067356233,62
"", "Pellentesque eget ante sit amet turpis vestibulum posuere ut non ipsum. Suspendisse potenti. ",1202122311,63
"Pellentesque eget ante sit", "Pellentesque fringilla mi eu diam fermentum condimentum",1200010001,64
"Praesent pellentesque quam nec", "Praesent pellentesque quam nec ligula accumsan faucibus. Duis non nisi ante. Mauris eu ullamcorper urna.",1200000000,65
"Pellentesque habitant morbi tristique", "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus elit risus, interdum sed iaculis a, vehicula in eros.",1000000000,66
"Mauris lobortis luctus risus mattis luctus", "Mauris lobortis luctus risus mattis luctus. Praesent metus mi, euismod quis accumsan vel, placerat id dui. Donec sed erat vel arcu hendrerit hendrerit nec posuere metus! Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.",1202012011,67
"Mauris sed felis ut tortor gravida", "Mauris sed felis ut tortor gravida vestibulum vel ac enim!",1202123943,68
"Sed vehicula, ipsum non dignissim tristique", "Sed vehicula, ipsum non dignissim tristique, urna dui gravida elit, id tempor nunc eros sit amet ligula.",1202323423,69
"Duis consequat sagittis lectus id semper", "Duis consequat sagittis lectus id semper. Phasellus semper ante at leo faucibus venenatis.",1203124344,70
"Nunc malesuada convallis neque", "Nunc malesuada convallis neque ac tincidunt. Etiam hendrerit mi at arcu bibendum eget viverra mi fringilla.",1202334234,71
"Donec et ante mi?", "Donec et ante mi? Nullam auctor suscipit nibh quis dignissim. Etiam non lorem eros, vel auctor quam.",1205646554,72
"Cras consequat", "Cras consequat, ligula quis pulvinar ultrices, dui sem venenatis leo, et dignissim ante mi vitae ipsum.",1202345600,73
"Suspendisse convallis tempor adipiscing", "Suspendisse convallis tempor adipiscing. Vivamus ut ullamcorper nulla.",1202203200,74
"Vestibulum ante ipsum primis in faucibus orci luctus", "Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae.",1202202300,75
"Maecenas consectetur quam ac risus iaculis pharetra", "Maecenas consectetur quam ac risus iaculis pharetra. Nam metus velit, mattis ac interdum ac, volutpat et diam.",1202323430,76
"Ut odio massa", "Ut odio massa, luctus aliquam pretium non, imperdiet quis risus.",1202200000,77
"Curabitur sapien neque", "Curabitur sapien neque, elementum nec iaculis non, commodo nec arcu.",1206000000,78
"Duis a arcu felis", "Duis a arcu felis, id tristique lectus. Nullam porta mi vitae erat suscipit vulputate?",1202906458,79
"Cras sollicitudin lobortis rutrum", "Cras sollicitudin lobortis rutrum. Nunc vitae nisl nec orci laoreet cursus.",1204534599,80
"Cras fringilla commodo posuere", "Cras fringilla commodo posuere. Nam sed justo dolor, vel pharetra odio.",1205345344,81
"In fringilla erat et mi consequat convallis", "In fringilla erat et mi consequat convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.",1202455443,82
"Aliquam in tellus nibh", "Aliquam in tellus nibh, ut pharetra metus. Fusce tempor, lectus eget ultrices sagittis, ipsum est sagittis urna, vel porttitor magna sem ac diam.",1207566663,83
"Nunc gravida, leo sed faucibus viverra", "Nunc gravida, leo sed faucibus viverra, orci sapien mollis tellus, sit amet venenatis odio augue eu nunc.",1203453245,84
"Vestibulum tristique sodales arcu", "Vestibulum tristique sodales arcu, nec dignissim mauris rutrum et.",1202230010,85
"Praesent porttitor viverra rhoncus", "Praesent porttitor viverra rhoncus! Nulla malesuada elit et diam semper quis vehicula metus euismod.",1209200010,86
Can't render this file because it contains an unexpected character in line 5 and column 16.

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<title>2 date values</title>
<guid>123456789</guid>
<date>Wed, 06 Jan 2010 15:05:00 GMT+00:00</date>
<date>Thu, 07 Jan 2010 15:08:00 GMT+00:00</date>
</item>
<item>
<title>4 date values</title>
<guid>1234567890</guid>
<date>Wed, 06 Jan 2010 15:00:00 GMT+00:00</date>
<date>Thu, 07 Jan 2010 15:00:00 GMT+00:00</date>
<date>Fri, 08 Jan 2010 15:00:00 GMT+00:00</date>
<date>Sat, 09 Jan 2010 15:00:00 GMT+00:00</date>
</item>
<item>
<title>Bogus date values</title>
<guid>1234567892</guid>
<date>Wed, 36 Jan 2010 15:00:00 GMT+00:00</date>
<date>Foo, 07 Bar 2010 95:00:00 GMT+00:00</date>
<date>This is just pure bogus. No date here!</date>
</item>
<item>
<title>Single date value</title>
<guid>1234567894</guid>
<date>Wed, 06 Jan 2010 14:00:00 GMT+00:00</date>
</item>
</items>

View File

@@ -0,0 +1,2 @@
"guid","title","body","date","datestamp","datetime","image","image_alt","image_title","link","list_boolean","number_decimal","number_float","number_integer","term","text"
1,,,,,,,,,,,,,,,
1 guid title body date datestamp datetime image image_alt image_title link list_boolean number_decimal number_float number_integer term text
2 1

View File

@@ -0,0 +1 @@
"guid","title_en","title_fr","body_en","body_fr","date_en","date_fr","datestamp_en","datestamp_fr","datetime_en","datetime_fr","image_en","image_fr","image_alt_en","image_alt_fr","image_title_en","image_title_fr","link_en","link_fr","list_boolean_en","list_boolean_fr","number_decimal_en","number_decimal_fr","number_float_en","number_float_fr","number_integer_en","number_integer_fr","term_en","term_fr","text_en","text_fr"
Can't render this file because it contains an unexpected character in line 1 and column 424.

View File

@@ -0,0 +1 @@
"guid","title_en","title_fr","body_en","body_fr","date_en","date_fr","datestamp_en","datestamp_fr","datetime_en","datetime_fr","image_en","image_fr","image_alt_en","image_alt_fr","image_title_en","image_title_fr","link_en","link_fr","list_boolean_en","list_boolean_fr","number_decimal_en","number_decimal_fr","number_float_en","number_float_fr","number_integer_en","number_integer_fr","term_en","term_fr","text_en","text_fr"
Can't render this file because it contains an unexpected character in line 1 and column 424.

View File

@@ -0,0 +1,2 @@
"guid","title","body","date","datestamp","datetime","image","image_alt","image_title","link","list_boolean","number_decimal","number_float","number_integer","term","text"
1,"Teste Feeds Multilingue 1","Ceci est la corps","05-11-1955",-446731187,"1955-11-05 12:00:13","public://images/la fayette.jpeg","La Fayette","la Fayette dans les bois","http://google.fr",1,1.2,5.6295,2000,"Nouvelles","Carottes"
1 guid title body date datestamp datetime image image_alt image_title link list_boolean number_decimal number_float number_integer term text
2 1 Teste Feeds Multilingue 1 Ceci est la corps 05-11-1955 -446731187 1955-11-05 12:00:13 public://images/la fayette.jpeg La Fayette la Fayette dans les bois http://google.fr 1 1.2 5.6295 2000 Nouvelles Carottes

View File

@@ -0,0 +1,2 @@
"guid","title","body","date","datestamp","datetime","image","image_alt","image_title","link","list_boolean","number_decimal","number_float","number_integer","term","text"
1,"Feeds-meertaligheid 1 testen","Dit is de berichttekst","29-07-1985",491460492,"1985-07-29 4:48:12","public://images/attersee.jpeg","Bij het zien","Bij het zien van de groene vloeistof","http://google.nl",1,30.3,30.2795,30,"Nieuws","Wortelen"
1 guid title body date datestamp datetime image image_alt image_title link list_boolean number_decimal number_float number_integer term text
2 1 Feeds-meertaligheid 1 testen Dit is de berichttekst 29-07-1985 491460492 1985-07-29 4:48:12 public://images/attersee.jpeg Bij het zien Bij het zien van de groene vloeistof http://google.nl 1 30.3 30.2795 30 Nieuws Wortelen

View File

@@ -0,0 +1,4 @@
"guid","title","summary","body"
1,"Lorem ipsum","Lorem ipsum summary","Lorem ipsum body"
2,"Ut wisi enim ad minim veniam","","Ut wisi enim ad minim veniam body"
3,"Duis autem vel eum iriure dolor","",""
1 guid title summary body
2 1 Lorem ipsum Lorem ipsum summary Lorem ipsum body
3 2 Ut wisi enim ad minim veniam Ut wisi enim ad minim veniam body
4 3 Duis autem vel eum iriure dolor

View File

@@ -0,0 +1,10 @@
Title,Body,published,GUID
"Ut wisi enim ad minim veniam", "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.",205200720,2
"Duis autem vel eum iriure dolor", "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.",428112720,3
"Nam liber tempor", "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.",1151766000,1
Typi non habent"", "Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem.",1256326995,4
"Lorem ipsum","Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.",1251936720,1
"Investigationes demonstraverunt", "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.",946702800,5
"Claritas est etiam", "Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum.",438112720,6
"Mirum est notare", "Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima.",1151066000,7
"Eodem modo typi", "Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.",1201936720,8
Can't render this file because it contains an unexpected character in line 5 and column 16.

View File

@@ -0,0 +1,10 @@
Title|Body|published|GUID
"Ut wisi enim ad minim veniam"| "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat."|205200720|2
"Duis autem vel eum iriure dolor"| "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi."|428112720|3
"Nam liber tempor"| "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum."|1151766000|1
Typi non habent""| "Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem."|1256326995|4
"Lorem ipsum"|"Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat."|1251936720|1
"Investigationes demonstraverunt"| "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius."|946702800|5
"Claritas est etiam"| "Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum."|438112720|6
"Mirum est notare"| "Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima."|1151066000|7
"Eodem modo typi"| "Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum."|1201936720|8
Can't render this file because it contains an unexpected character in line 5 and column 16.

View File

@@ -0,0 +1,10 @@
Title+Body+published+GUID
"Ut wisi enim ad minim veniam"+ "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat."+205200720+2
"Duis autem vel eum iriure dolor"+ "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi."+428112720+3
"Nam liber tempor"+ "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum."+1151766000+1
Typi non habent""+ "Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem."+1256326995+4
"Lorem ipsum"+"Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat."+1251936720+1
"Investigationes demonstraverunt"+ "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius."+946702800+5
"Claritas est etiam"+ "Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum."+438112720+6
"Mirum est notare"+ "Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima."+1151066000+7
"Eodem modo typi"+ "Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum."+1201936720+8
Can't render this file because it contains an unexpected character in line 2 and column 30.

View File

@@ -0,0 +1,10 @@
Title;Body;published;GUID
"Ut wisi enim ad minim veniam"; "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.";205200720;2
"Duis autem vel eum iriure dolor"; "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.";428112720;3
"Nam liber tempor"; "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.";1151766000;1
Typi non habent""; "Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem.";1256326995;4
"Lorem ipsum";"Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.";1251936720;1
"Investigationes demonstraverunt"; "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.";946702800;5
"Claritas est etiam"; "Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum.";438112720;6
"Mirum est notare"; "Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima.";1151066000;7
"Eodem modo typi"; "Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.";1201936720;8
Can't render this file because it contains an unexpected character in line 5 and column 16.

View File

@@ -0,0 +1,10 @@
Title Body published GUID
"Ut wisi enim ad minim veniam" "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat." 205200720 2
"Duis autem vel eum iriure dolor" "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi." 428112720 3
"Nam liber tempor" "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum." 1151766000 1
Typi non habent"" "Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem." 1256326995 4
"Lorem ipsum" "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat." 1251936720 1
"Investigationes demonstraverunt" "Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius." 946702800 5
"Claritas est etiam" "Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum." 438112720 6
"Mirum est notare" "Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima." 1151066000 7
"Eodem modo typi" "Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum." 1201936720 8
Can't render this file because it contains an unexpected character in line 2 and column 33.

View File

@@ -0,0 +1,6 @@
"guid","title","tags"
"1","Lorem Ipsum 1","term1"
"2","Lorem Ipsum 2",""
"3","Lorem Ipsum 3",
"4","Lorem Ipsum 4"," "
"5","Lorem Ipsum 5","0"
1 guid title tags
2 1 Lorem Ipsum 1 term1
3 2 Lorem Ipsum 2
4 3 Lorem Ipsum 3
5 4 Lorem Ipsum 4
6 5 Lorem Ipsum 5 0

View File

@@ -0,0 +1,3 @@
guid,name,parent,parentguid
1,Europe,,
2,Belgium,Europe,1
1 guid name parent parentguid
2 1 Europe
3 2 Belgium Europe 1

View File

@@ -0,0 +1,5 @@
name,mail,since,password
Morticia,morticia@example.com,1244347500,mort
Gomez,gomez@example.com,1228572000,gome
Wednesday,wednesdayexample.com,1228347137,wedn
Pugsley,pugsley@example,1228260225,pugs
1 name mail since password
2 Morticia morticia@example.com 1244347500 mort
3 Gomez gomez@example.com 1228572000 gome
4 Wednesday wednesdayexample.com 1228347137 wedn
5 Pugsley pugsley@example 1228260225 pugs

View File

@@ -0,0 +1,6 @@
name,mail,since,password
Morticia,morticia@example.com,1363959643,mort
Fester,fester@example.com,1363959643,fest
Gomez,gomez@example.com,1363959643,gome
Wednesday,wednesdayexample.com,1363959643,wedn
Pugsley,pugsley@example,1363959643,pugs
1 name mail since password
2 Morticia morticia@example.com 1363959643 mort
3 Fester fester@example.com 1363959643 fest
4 Gomez gomez@example.com 1363959643 gome
5 Wednesday wednesdayexample.com 1363959643 wedn
6 Pugsley pugsley@example 1363959643 pugs

View File

@@ -38,5 +38,16 @@ class FeedsDateTimeTest extends FeedsWebTestCase {
$this->assertTrue(is_numeric($date->format('U')));
$date = new FeedsDateTime('12/3/2009 20:00:10');
$this->assertTrue(is_numeric($date->format('U')));
// Check that years above 2000 work correctly.
$date1 = new FeedsDateTime(2012);
$date2 = new FeedsDateTime('January 2012');
$this->assertEqual($date1->format('U'), $date2->format('U'));
// Check that years before 1902 work correctly.
$early_date_string = '01/02/1901';
$date = new FeedsDateTime($early_date_string);
$this->assertEqual($date->format('m/d/Y'), $early_date_string);
}
}

View File

@@ -17,18 +17,14 @@ class FeedsFileFetcherTestCase extends FeedsWebTestCase {
);
}
/**
* Test scheduling on cron.
*/
public function test() {
public function testPublicFiles() {
// Set up an importer.
$this->createImporterConfiguration('Node import', 'node');
// Set and configure plugins and mappings.
$edit = array(
'content_type' => '',
);
$this->drupalPost('admin/structure/feeds/node/settings', $edit, 'Save');
$this->setSettings('node', NULL, array('content_type' => ''));
$this->setPlugin('node', 'FeedsFileFetcher');
$this->setPlugin('node', 'FeedsCSVParser');
$mappings = array(
@@ -40,15 +36,19 @@ class FeedsFileFetcherTestCase extends FeedsWebTestCase {
$this->addMappings('node', $mappings);
// Straight up upload is covered in other tests, focus on direct mode
// and file batching here.
$this->setSettings('node', 'FeedsFileFetcher', array('direct' => TRUE));
$settings = array(
'direct' => TRUE,
'directory' => 'public://feeds',
);
$this->setSettings('node', 'FeedsFileFetcher', $settings);
// Verify that invalid paths are not accepted.
foreach (array('private://', '/tmp/') as $path) {
foreach (array('/tmp/') as $path) {
$edit = array(
'feeds[FeedsFileFetcher][source]' => $path,
);
$this->drupalPost('import/node', $edit, t('Import'));
$this->assertText("File needs to reside within the site's file directory, its path needs to start with public://.");
$this->assertText("The file needs to reside within the site's files directory, its path needs to start with scheme://. Available schemes:");
$count = db_query("SELECT COUNT(*) FROM {feeds_source} WHERE feed_nid = 0")->fetchField();
$this->assertEqual($count, 0);
}
@@ -67,4 +67,48 @@ class FeedsFileFetcherTestCase extends FeedsWebTestCase {
$this->drupalPost('import/node', $edit, t('Import'));
$this->assertText('Created 18 nodes');
}
/**
* Test uploading private files.
*/
public function testPrivateFiles() {
// Set up an importer.
$this->createImporterConfiguration('Node import', 'node');
// Set and configure plugins and mappings.
$edit = array(
'content_type' => '',
);
$this->drupalPost('admin/structure/feeds/node/settings', $edit, 'Save');
$this->setPlugin('node', 'FeedsFileFetcher');
$this->setPlugin('node', 'FeedsCSVParser');
$mappings = array(
'0' => array(
'source' => 'title',
'target' => 'title',
),
);
$this->addMappings('node', $mappings);
// Straight up upload is covered in other tests, focus on direct mode
// and file batching here.
$settings = array(
'direct' => TRUE,
'directory' => 'private://feeds',
);
$this->setSettings('node', 'FeedsFileFetcher', $settings);
// Verify batching through directories.
// Copy directory of files.
$dir = 'private://batchtest';
$this->copyDir($this->absolutePath() . '/tests/feeds/batch', $dir);
// Ingest directory of files. Set limit to 5 to force processor to batch,
// too.
variable_set('feeds_process_limit', 5);
$edit = array(
'feeds[FeedsFileFetcher][source]' => $dir,
);
$this->drupalPost('import/node', $edit, t('Import'));
$this->assertText('Created 18 nodes');
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* @file
* Contains FeedsFileHTTPTestCase.
*/
/**
* HTTP fetcher test class.
*/
class FeedsFileHTTPTestCase extends FeedsWebTestCase {
public static function getInfo() {
return array(
'name' => 'Fetcher: HTTP',
'description' => 'Tests for file http fetcher plugin.',
'group' => 'Feeds',
);
}
/**
* Test the Feed URL form.
*/
public function testFormValidation() {
// Set up an importer.
$id = drupal_strtolower($this->randomName());
$this->createImporterConfiguration($this->randomString(), $id);
// Check that by default, we add http:// to the front of the URL.
$edit = array(
'feeds[FeedsHTTPFetcher][source]' => 'example.com',
);
$this->drupalPost('import/' . $id, $edit, t('Import'));
$this->assertText(t('There are no new nodes.'));
$this->assertFieldByName('feeds[FeedsHTTPFetcher][source]', 'http://example.com');
$this->setSettings($id, 'FeedsHTTPFetcher', array('auto_scheme' => 'feed'));
$this->drupalPost('import/' . $id, $edit, t('Import'));
$this->assertText(t('There are no new nodes.'));
$this->assertFieldByName('feeds[FeedsHTTPFetcher][source]', 'feed://example.com');
$this->setSettings($id, 'FeedsHTTPFetcher', array('auto_scheme' => ''));
$this->drupalPost('import/' . $id, $edit, t('Import'));
$this->assertText(t('The URL example.com is invalid.'));
$this->assertFieldByName('feeds[FeedsHTTPFetcher][source]', 'example.com');
}
}

View File

@@ -0,0 +1,133 @@
<?php
/**
* @file
* Contains Feedsi18nTestCase.
*/
/**
* Tests importing data in a language.
*/
class Feedsi18nTestCase extends FeedsMapperTestCase {
/**
* The entity type to be tested.
*
* @var string
*/
protected $entityType;
/**
* The processor being used.
*
* @var string
*/
protected $processorName;
public function setUp($modules = array(), $permissions = array()) {
$modules = array_merge($modules, array(
'locale',
));
$permissions = array_merge(array(
'administer languages',
));
parent::setUp($modules, $permissions);
// Setup other languages.
$edit = array(
'langcode' => 'nl',
);
$this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
$this->assertText(t('The language Dutch has been created and can now be used.'));
$edit = array(
'langcode' => 'de',
);
$this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
$this->assertText(t('The language German has been created and can now be used.'));
// Include FeedsProcessor.inc to make its constants available.
module_load_include('inc', 'feeds', 'plugins/FeedsProcessor');
// Create and configure importer.
$this->createImporterConfiguration('Multilingual term importer', 'i18n');
$this->setPlugin('i18n', 'FeedsFileFetcher');
$this->setPlugin('i18n', 'FeedsCSVParser');
$this->setPlugin('i18n', $this->processorName);
}
/**
* Tests if entities get the language assigned that is set in the processor.
*/
public function testImport() {
// Import content in German.
$this->importFile('i18n', $this->absolutePath() . '/tests/feeds/content.csv');
// Assert that the entity's language is in German.
$entities = entity_load($this->entityType, array(1, 2));
foreach ($entities as $entity) {
$this->assertEqual('de', entity_language($this->entityType, $entity));
}
}
/**
* Tests if entities get a different language assigned when the processor's language
* is changed.
*/
public function testChangedLanguageImport() {
// Import content in German.
$this->importFile('i18n', $this->absolutePath() . '/tests/feeds/content.csv');
// Change processor's language to Dutch.
$this->setSettings('i18n', $this->processorName, array('language' => 'nl'));
// Re-import content.
$this->importFile('i18n', $this->absolutePath() . '/tests/feeds/content.csv');
// Assert that the entity's language is now in Dutch.
$entities = entity_load($this->entityType, array(1, 2));
foreach ($entities as $entity) {
$this->assertEqual('nl', entity_language($this->entityType, $entity));
}
}
/**
* Tests if items are imported in LANGUAGE_NONE if the processor's language is disabled.
*/
public function testDisabledLanguage() {
// Disable the German language.
$path = 'admin/config/regional/language';
$edit = array(
'enabled[de]' => FALSE,
);
$this->drupalPost($path, $edit, t('Save configuration'));
// Import content.
$this->importFile('i18n', $this->absolutePath() . '/tests/feeds/content.csv');
// Assert that the entities have no language assigned.
$entities = entity_load($this->entityType, array(1, 2));
foreach ($entities as $entity) {
$language = entity_language($this->entityType, $entity);
$this->assertEqual(LANGUAGE_NONE, $language, format_string('The entity is language neutral (actual: !language).', array('!language' => $language)));
}
}
/**
* Tests if items are imported in LANGUAGE_NONE if the processor's language is removed.
*/
public function testRemovedLanguage() {
// Remove the German language.
$path = 'admin/config/regional/language/delete/de';
$this->drupalPost($path, array(), t('Delete'));
// Import content.
$this->importFile('i18n', $this->absolutePath() . '/tests/feeds/content.csv');
// Assert that the entities have no language assigned.
$entities = entity_load($this->entityType, array(1, 2));
foreach ($entities as $entity) {
$language = entity_language($this->entityType, $entity);
$this->assertEqual(LANGUAGE_NONE, $language, format_string('The entity is language neutral (actual: !language).', array('!language' => $language)));
}
}
}

View File

@@ -0,0 +1,136 @@
<?php
/**
* @file
* Contains Feedsi18nNodeTestCase.
*/
/**
* Tests importing nodes in a language.
*/
class Feedsi18nNodeTestCase extends Feedsi18nTestCase {
/**
* Name of created content type.
*
* @var string
*/
private $contentType;
public static function getInfo() {
return array(
'name' => 'Multilingual content',
'description' => 'Tests Feeds multilingual support for nodes.',
'group' => 'Feeds',
'dependencies' => array('locale'),
);
}
public function setUp($modules = array(), $permissions = array()) {
$this->entityType = 'node';
$this->processorName = 'FeedsNodeProcessor';
parent::setUp($modules, $permissions);
// Create content type.
$this->contentType = $this->createContentType();
// Configure importer.
$this->setSettings('i18n', $this->processorName, array(
'bundle' => $this->contentType,
'language' => 'de',
'update_existing' => FEEDS_UPDATE_EXISTING,
'skip_hash_check' => TRUE,
));
$this->addMappings('i18n', array(
0 => array(
'source' => 'guid',
'target' => 'guid',
'unique' => '1',
),
1 => array(
'source' => 'title',
'target' => 'title',
),
));
}
/**
* Tests if the language setting is available on the processor.
*/
public function testAvailableProcessorLanguageSetting() {
// Check if the language setting is available when the locale module is enabled.
$this->drupalGet('admin/structure/feeds/i18n/settings/FeedsNodeProcessor');
$this->assertField('language', 'Language field is available on the node processor settings when the locale module is enabled.');
// Disable the locale module and check if the language setting is no longer available.
module_disable(array('locale'));
$this->drupalGet('admin/structure/feeds/i18n/settings/FeedsNodeProcessor');
$this->assertNoField('language', 'Language field is not available on the node processor settings when the locale module is disabled.');
}
/**
* Tests processor language setting in combination with language mapping target.
*/
public function testWithLanguageMappingTarget() {
$this->addMappings('i18n', array(
2 => array(
'source' => 'language',
'target' => 'language',
),
));
// Import csv file. The first item has a language specified (Dutch), the second
// one has no language specified and should be imported in the processor's language (German).
$this->importFile('i18n', $this->absolutePath() . '/tests/feeds/content_i18n.csv');
// The first node should be Dutch.
$node = node_load(1);
$this->assertEqual('nl', entity_language('node', $node), 'Item 1 has the Dutch language assigned.');
// The second node should be German.
$node = node_load(2);
$this->assertEqual('de', entity_language('node', $node), 'Item 2 has the German language assigned.');
}
/**
* Tests if nodes get imported in LANGUAGE_NONE when the locale module gets disabled.
*/
public function testDisabledLocaleModule() {
module_disable(array('locale'));
// Make sure that entity info is reset.
drupal_flush_all_caches();
drupal_static_reset();
// Import content.
$this->importFile('i18n', $this->absolutePath() . '/tests/feeds/content.csv');
// Assert that the content has no language assigned.
for ($i = 1; $i <= 2; $i++) {
$node = node_load($i);
$language = entity_language('node', $node);
$this->assertEqual(LANGUAGE_NONE, $language, format_string('The node is language neutral (actual: !language).', array('!language' => $language)));
}
}
/**
* Tests if nodes get imported in LANGUAGE_NONE when the locale module gets uninstalled.
*/
public function testUninstalledLocaleModule() {
module_disable(array('locale'));
drupal_uninstall_modules(array('locale'));
// Make sure that entity info is reset.
drupal_flush_all_caches();
drupal_static_reset();
// Import content.
$this->importFile('i18n', $this->absolutePath() . '/tests/feeds/content.csv');
// Assert that the content has no language assigned.
for ($i = 1; $i <= 2; $i++) {
$node = node_load($i);
$language = entity_language('node', $node);
$this->assertEqual(LANGUAGE_NONE, $language, format_string('The node is language neutral (actual: !language).', array('!language' => $language)));
}
}
}

View File

@@ -0,0 +1,119 @@
<?php
/**
* @file
* Contains Feedsi18nTaxonomyTestCase.
*/
/**
* Tests importing terms in a language.
*/
class Feedsi18nTaxonomyTestCase extends Feedsi18nTestCase {
/**
* Name of created vocabulary.
*
* @var string
*/
private $vocabulary;
public static function getInfo() {
return array(
'name' => 'Multilingual terms',
'description' => 'Tests Feeds multilingual support for taxonomy terms.',
'group' => 'Feeds',
'dependencies' => array('locale', 'i18n_taxonomy'),
);
}
public function setUp($modules = array(), $permissions = array()) {
$this->entityType = 'taxonomy_term';
$this->processorName = 'FeedsTermProcessor';
$modules = array_merge($modules, array(
'i18n_taxonomy',
));
parent::setUp($modules, $permissions);
// Create vocabulary.
$this->vocabulary = strtolower($this->randomName(8));
$edit = array(
'name' => $this->vocabulary,
'machine_name' => $this->vocabulary,
);
$this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
// Configure importer.
$this->setSettings('i18n', $this->processorName, array(
'bundle' => $this->vocabulary,
'language' => 'de',
'update_existing' => FEEDS_UPDATE_EXISTING,
'skip_hash_check' => TRUE,
));
$this->addMappings('i18n', array(
0 => array(
'source' => 'guid',
'target' => 'guid',
'unique' => '1',
),
1 => array(
'source' => 'title',
'target' => 'name',
),
));
}
/**
* Tests if the language setting is available on the processor.
*/
public function testAvailableProcessorLanguageSetting() {
// Check if the language setting is available when the i18n_taxonomy module is enabled.
$this->drupalGet('admin/structure/feeds/i18n/settings/FeedsTermProcessor');
$this->assertField('language', 'Language field is available on the term processor settings when the i18n_taxonomy module is enabled.');
// Disable the i18n_taxonomy module and check if the language setting is no longer available.
module_disable(array('i18n_taxonomy'));
$this->drupalGet('admin/structure/feeds/i18n/settings/FeedsTermProcessor');
$this->assertNoField('language', 'Language field is not available on the term processor settings when the i18n_taxonomy module is disabled.');
}
/**
* Tests if terms get imported in LANGUAGE_NONE when the i18n_taxonomy module gets disabled.
*/
public function testDisabledi18nTaxonomyModule() {
module_disable(array('i18n_taxonomy'));
// Make sure that entity info is reset.
drupal_flush_all_caches();
drupal_static_reset();
// Import content.
$this->importFile('i18n', $this->absolutePath() . '/tests/feeds/content.csv');
// Assert that the terms have no language assigned.
$entities = entity_load($this->entityType, array(1, 2));
foreach ($entities as $entity) {
// Terms shouldn't have a language property.
$this->assertFalse(isset($entity->language), 'The term does not have a language.');
}
}
/**
* Tests if terms get imported in LANGUAGE_NONE when the i18n_taxonomy module gets uninstalled.
*/
public function testUninstalledi18nTaxonomyModule() {
module_disable(array('i18n_taxonomy'));
drupal_uninstall_modules(array('i18n_taxonomy'));
// Make sure that entity info is reset.
drupal_flush_all_caches();
drupal_static_reset();
// Import content.
$this->importFile('i18n', $this->absolutePath() . '/tests/feeds/content.csv');
// Assert that the terms have no language assigned.
$entities = entity_load($this->entityType, array(1, 2));
foreach ($entities as $entity) {
$this->assertFalse(isset($entity->language), 'The term does not have a language.');
}
}
}

View File

@@ -2,11 +2,11 @@
/**
* @file
* Helper class with auxiliary functions for feeds mapper module tests.
* Contains FeedsMapperTestCase.
*/
/**
* Base class for implementing Feeds Mapper test cases.
* Helper class with auxiliary functions for feeds mapper module tests.
*/
class FeedsMapperTestCase extends FeedsWebTestCase {
@@ -19,13 +19,19 @@ class FeedsMapperTestCase extends FeedsWebTestCase {
'email' => 'email_textfield',
'emimage' => 'emimage_textfields',
'emaudio' => 'emaudio_textfields',
'filefield' => 'filefield_widget',
'image' => 'imagefield_widget',
'file' => 'file_generic',
'image' => 'image_image',
'link_field' => 'link_field',
'list_boolean' => 'options_onoff',
'list_float' => 'options_select',
'list_integer' => 'options_select',
'list_text' => 'options_select',
'number_float' => 'number',
'number_integer' => 'number',
'nodereference' => 'nodereference_select',
'text' => 'text_textfield',
'text_long' => 'text_textarea',
'text_with_summary' => 'text_textarea_with_summary',
'userreference' => 'userreference_select',
);
@@ -52,6 +58,29 @@ class FeedsMapperTestCase extends FeedsWebTestCase {
}
}
/**
* Assert that a form field for the given field with the given value
* does not exist in the current form.
*
* @param $field_name
* The name of the field.
* @param $value
* The (raw) value of the field.
* @param $index
* The index of the field (for q multi-valued field).
*
* @see FeedsMapperTestCase::getFormFieldsNames()
* @see FeedsMapperTestCase::getFormFieldsValues()
*/
protected function assertNoNodeFieldValue($field_name, $value, $index = 0) {
$names = $this->getFormFieldsNames($field_name, $index);
$values = $this->getFormFieldsValues($field_name, $value);
foreach ($names as $k => $name) {
$value = $values[$k];
$this->assertNoFieldByName($name, $value, t('Did not find form field %name for %field_name with the value %value.', array('%name' => $name, '%field_name' => $field_name, '%value' => $value)));
}
}
/**
* Returns the form fields names for a given CCK field. Default implementation
* provides support for a single form field with the following name pattern
@@ -157,4 +186,5 @@ class FeedsMapperTestCase extends FeedsWebTestCase {
$field_widgets = FeedsMapperTestCase::$field_widgets;
return isset($field_widgets[$field_type]) ? $field_widgets[$field_type] : NULL;
}
}

View File

@@ -2,13 +2,14 @@
/**
* @file
* Test cases for Feeds mapping configuration form.
* Contains FeedsMapperConfigTestCase.
*/
/**
* Class for testing basic Feeds ajax mapping configurtaion form behavior.
* Test cases for Feeds mapping configuration form.
*/
class FeedsMapperConfigTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: Config',
@@ -37,6 +38,8 @@ class FeedsMapperConfigTestCase extends FeedsMapperTestCase {
// Click gear to get form.
$this->drupalPostAJAX(NULL, array(), 'mapping_settings_edit_0');
$second_callback_value = $this->randomString();
// Set some settings.
$edit = array(
'config[0][settings][checkbox]' => 1,
@@ -44,8 +47,10 @@ class FeedsMapperConfigTestCase extends FeedsMapperTestCase {
'config[0][settings][textarea]' => 'Textarea value: Didery dofffffffffffffffffffffffffffffffffffff',
'config[0][settings][radios]' => 'option1',
'config[0][settings][select]' => 'option4',
'config[0][settings][second_value]' => $second_callback_value,
);
$this->drupalPostAJAX(NULL, $edit, 'mapping_settings_update_0');
$this->assertText(t('* Changes made to target configuration are stored temporarily. Click Save to make your changes permanent.'));
// Click Save.
$this->drupalPost(NULL, array(), t('Save'));
@@ -59,6 +64,7 @@ class FeedsMapperConfigTestCase extends FeedsMapperTestCase {
$this->assertText('Textarea value: Didery dofffffffffffffffffffffffffffffffffffff');
$this->assertText('Radios value: Option 1');
$this->assertText('Select value: Another One');
$this->assertText(t('Second summary: @value', array('@value' => $second_callback_value)));
// Check that settings are in db.
$config = unserialize(db_query("SELECT config FROM {feeds_importer} WHERE id='syndication'")->fetchField());
@@ -69,7 +75,7 @@ class FeedsMapperConfigTestCase extends FeedsMapperTestCase {
$this->assertEqual($settings['textarea'], 'Textarea value: Didery dofffffffffffffffffffffffffffffffffffff');
$this->assertEqual($settings['radios'], 'option1');
$this->assertEqual($settings['select'], 'option4');
$this->assertEqual($settings['second_value'], $second_callback_value);
// Check that form validation works.
// Click gear to get form.
@@ -112,4 +118,5 @@ class FeedsMapperConfigTestCase extends FeedsMapperTestCase {
$this->assertText('Checkbox inactive.');
$this->assertText('Second mapping text');
}
}

View File

@@ -2,16 +2,17 @@
/**
* @file
* Test case for CCK date field mapper mappers/date.inc.
* Contains FeedsMapperDateTestCase.
*/
/**
* Class for testing Feeds <em>content</em> mapper.
* Test case for CCK date field mapper mappers/date.inc.
*
* @todo: Add test method iCal
* @todo: Add test method for end date
*/
class FeedsMapperDateTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: Date',
@@ -39,12 +40,33 @@ class FeedsMapperDateTestCase extends FeedsMapperTestCase {
//'datetime' => 'datetime', // REMOVED because the field is broken ATM.
));
// Hack to get date fields to not round to every 15 minutes.
foreach (array('date', 'datestamp') as $field) {
$field = 'field_' . $field;
$edit = array(
'widget_type' => 'date_select',
);
$this->drupalPost('admin/structure/types/manage/' . $typename . '/fields/' . $field . '/widget-type', $edit, 'Continue');
$edit = array(
'instance[widget][settings][increment]' => 1,
);
$this->drupalPost('admin/structure/types/manage/' . $typename . '/fields/' . $field, $edit, 'Save settings');
$edit = array(
'widget_type' => 'date_text',
);
$this->drupalPost('admin/structure/types/manage/' . $typename . '/fields/' . $field . '/widget-type', $edit, 'Continue');
}
// Create and configure importer.
$this->createImporterConfiguration('Date RSS', 'daterss');
$this->setSettings('daterss', NULL, array('content_type' => '', 'import_period' => FEEDS_SCHEDULE_NEVER));
$this->setSettings('daterss', NULL, array(
'content_type' => '',
'import_period' => FEEDS_SCHEDULE_NEVER,
));
$this->setPlugin('daterss', 'FeedsFileFetcher');
$this->setPlugin('daterss', 'FeedsSyndicationParser');
$this->setSettings('daterss', 'FeedsNodeProcessor', array('content_type' => $typename));
$this->setSettings('daterss', 'FeedsNodeProcessor', array(
'bundle' => $typename,
));
$this->addMappings('daterss', array(
0 => array(
'source' => 'title',
@@ -81,7 +103,7 @@ class FeedsMapperDateTestCase extends FeedsMapperTestCase {
'01/06/2010 - 06:05',
'01/06/2010 - 11:26',
'01/07/2010 - 00:26',
);
);
for ($i = 1; $i <= 6; $i++) {
$this->drupalGet("node/$i/edit");
$this->assertNodeFieldValue('date', $values[$i-1]);
@@ -97,4 +119,154 @@ class FeedsMapperDateTestCase extends FeedsMapperTestCase {
return parent::getFormFieldsNames($field_name, $index);
}
}
/**
* Tests if values are cleared out when an empty value is provided.
*/
public function testClearOutValues() {
// Create content type.
$typename = $this->createContentType(array(), array(
'date' => 'date',
'datestamp' => 'datestamp',
'datetime' => 'datetime',
));
// Hack to get date fields to not round to every 15 minutes.
foreach (array('date', 'datestamp', 'datetime') as $field) {
$field = 'field_' . $field;
$edit = array(
'widget_type' => 'date_select',
);
$this->drupalPost('admin/structure/types/manage/' . $typename . '/fields/' . $field . '/widget-type', $edit, 'Continue');
$edit = array(
'instance[widget][settings][increment]' => 1,
'field[settings][enddate_get]' => 1,
);
$this->drupalPost('admin/structure/types/manage/' . $typename . '/fields/' . $field, $edit, 'Save settings');
$edit = array(
'widget_type' => 'date_text',
);
$this->drupalPost('admin/structure/types/manage/' . $typename . '/fields/' . $field . '/widget-type', $edit, 'Continue');
}
// Create and configure importer.
$this->createImporterConfiguration('Content CSV', 'csv');
$this->setSettings('csv', NULL, array(
'content_type' => '',
'import_period' => FEEDS_SCHEDULE_NEVER,
));
$this->setPlugin('csv', 'FeedsFileFetcher');
$this->setPlugin('csv', 'FeedsCSVParser');
$this->setSettings('csv', 'FeedsNodeProcessor', array(
'bundle' => $typename,
'update_existing' => 1,
));
$this->addMappings('csv', array(
0 => array(
'source' => 'title',
'target' => 'title',
'unique' => TRUE,
),
1 => array(
'source' => 'created',
'target' => 'field_date:start',
),
2 => array(
'source' => 'end',
'target' => 'field_date:end',
),
3 => array(
'source' => 'created',
'target' => 'field_datestamp:start',
),
4 => array(
'source' => 'end',
'target' => 'field_datestamp:end',
),
5 => array(
'source' => 'created',
'target' => 'field_datetime:start',
),
6 => array(
'source' => 'end',
'target' => 'field_datetime:end',
),
));
// Import CSV file.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_date.csv');
$this->assertText('Created 2 nodes');
// Check the imported nodes.
$date_values = array(
1 => array(
'created' => '09/03/2009 - 00:12',
'end' => '11/03/2012 - 09:58',
),
2 => array(
'created' => '09/02/2009 - 22:59',
'end' => '11/03/2012 - 08:46',
),
);
for ($i = 1; $i <= 2; $i++) {
$this->drupalGet("node/$i/edit");
$this->assertNodeFieldValue('date', $date_values[$i]['created']);
$this->assertFieldByName('field_date[und][0][value2][date]', $date_values[$i]['end']);
$this->assertNodeFieldValue('datestamp', $date_values[$i]['created']);
$this->assertFieldByName('field_datestamp[und][0][value2][date]', $date_values[$i]['end']);
$this->assertNodeFieldValue('datetime', $date_values[$i]['created']);
$this->assertFieldByName('field_datetime[und][0][value2][date]', $date_values[$i]['end']);
}
// Import CSV file with empty values.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_empty.csv');
$this->assertText('Updated 2 nodes');
// Check if all values were cleared out for both nodes.
for ($i = 1; $i <= 2; $i++) {
$this->drupalGet("node/$i/edit");
$this->assertNoNodeFieldValue('date', $date_values[$i]['created']);
$this->assertNoFieldByName('field_date[und][0][value2][date]', $date_values[$i]['end']);
$this->assertNoNodeFieldValue('datestamp', $date_values[$i]['created']);
$this->assertNoFieldByName('field_datestamp[und][0][value2][date]', $date_values[$i]['end']);
$this->assertNoNodeFieldValue('datetime', $date_values[$i]['created']);
$this->assertNoFieldByName('field_datetime[und][0][value2][date]', $date_values[$i]['end']);
$this->drupalGet("node/$i");
$this->assertNoText('date_label');
$this->assertNoText('datestamp_label');
$this->assertNoText('datetime_label');
}
// Re-import the first file again and check if the values returned.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_date.csv');
$this->assertText('Updated 2 nodes');
for ($i = 1; $i <= 2; $i++) {
$this->drupalGet("node/$i/edit");
$this->assertNodeFieldValue('date', $date_values[$i]['created']);
$this->assertFieldByName('field_date[und][0][value2][date]', $date_values[$i]['end']);
$this->assertNodeFieldValue('datestamp', $date_values[$i]['created']);
$this->assertFieldByName('field_datestamp[und][0][value2][date]', $date_values[$i]['end']);
$this->assertNodeFieldValue('datetime', $date_values[$i]['created']);
$this->assertFieldByName('field_datetime[und][0][value2][date]', $date_values[$i]['end']);
}
// Import CSV file with non-existent values.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_non_existent.csv');
$this->assertText('Updated 2 nodes');
// Check if all values were cleared out for node 1.
$this->drupalGet('node/1/edit');
$this->assertNoNodeFieldValue('date', $date_values[1]['created']);
$this->assertNoFieldByName('field_date[und][0][value2][date]', $date_values[1]['end']);
$this->assertNoNodeFieldValue('datestamp', $date_values[1]['created']);
$this->assertNoFieldByName('field_datestamp[und][0][value2][date]', $date_values[1]['end']);
$this->assertNoNodeFieldValue('datetime', $date_values[1]['created']);
$this->assertNoFieldByName('field_datetime[und][0][value2][date]', $date_values[1]['end']);
// Check if labels for fields that should be cleared out are not shown.
$this->drupalGet('node/1');
$this->assertNoText('date_label');
$this->assertNoText('datestamp_label');
$this->assertNoText('datetime_label');
}
}

View File

@@ -0,0 +1,120 @@
<?php
/**
* @file
* Contains FeedsMapperDateMultipleTestCase.
*/
/**
* Test case for CCK date multi-field mapper mappers/date.inc.
*
* @todo: Add test method iCal
* @todo: Add test method for end date
*/
class FeedsMapperDateMultipleTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: Date, multi value fields',
'description' => 'Test Feeds Mapper support for CCK multi valiue Date fields.',
'group' => 'Feeds',
'dependencies' => array('date', 'feeds_xpathparser'),
);
}
public function setUp() {
parent::setUp(array('date_api', 'date', 'feeds_xpathparser'));
variable_set('date_default_timezone', 'UTC');
}
/**
* Testing import by loading a 4 item XML file.
*/
public function test() {
$this->drupalGet('admin/config/regional/settings');
// Create content type.
$typename = $this->createContentType(array(), array(
'date' => 'date',
));
// Make the field hold unlimited values
$edit = array(
'field[cardinality]' => -1,
);
$this->drupalPost('admin/structure/types/manage/' . $typename . '/fields/field_date', $edit, 'Save settings');
$this->assertText('Saved date_date_label configuration');
// Create and configure importer.
$this->createImporterConfiguration('Multi dates', 'multidates');
$this->setSettings('multidates', NULL, array(
'content_type' => '',
'import_period' => FEEDS_SCHEDULE_NEVER,
));
$this->setPlugin('multidates', 'FeedsFileFetcher');
$this->setPlugin('multidates', 'FeedsXPathParserXML');
$this->setSettings('multidates', 'FeedsNodeProcessor', array(
'bundle' => $typename,
));
$this->addMappings('multidates', array(
0 => array(
'source' => 'xpathparser:0',
'target' => 'title',
),
1 => array(
'source' => 'xpathparser:1',
'target' => 'guid',
),
2 => array(
'source' => 'xpathparser:2',
'target' => 'field_date:start',
),
));
$edit = array(
'xpath[context]' => '//item',
'xpath[sources][xpathparser:0]' => 'title',
'xpath[sources][xpathparser:1]' => 'guid',
'xpath[sources][xpathparser:2]' => 'date',
'xpath[allow_override]' => FALSE,
);
$this->setSettings('multidates', 'FeedsXPathParserXML', $edit);
$edit = array(
'allowed_extensions' => 'xml',
'directory' => 'public://feeds',
);
$this->setSettings('multidates', 'FeedsFileFetcher', $edit);
// Import XML file.
$this->importFile('multidates', $this->absolutePath() . '/tests/feeds/multi-date.xml');
$this->assertText('Created 4 nodes');
// Check the imported nodes.
$values = array(
1 => array(
'01/06/2010 - 15:00',
'01/07/2010 - 15:15',
),
2 => array(
'01/06/2010 - 15:00',
'01/07/2010 - 15:00',
'01/08/2010 - 15:00',
'01/09/2010 - 15:00',
),
3 => array(
'', // Bogus date was filtered out.
),
4 => array(
'01/06/2010 - 14:00',
)
);
foreach ($values as $v => $key) {
$this->drupalGet("node/$v/edit");
foreach ($key as $delta => $value) {
$this->assertFieldById('edit-field-date-und-' . $delta . '-value-date', $value);
}
}
}
}

View File

@@ -2,13 +2,14 @@
/**
* @file
* Test case for simple CCK field mapper mappers/content.inc.
* Contains FeedsMapperFieldTestCase.
*/
/**
* Class for testing Feeds field mapper.
* Test case for simple CCK field mapper mappers/content.inc.
*/
class FeedsMapperFieldTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: Fields',
@@ -24,7 +25,7 @@ class FeedsMapperFieldTestCase extends FeedsMapperTestCase {
/**
* Basic test loading a double entry CSV file.
*/
function test() {
public function test() {
// Create content type.
$typename = $this->createContentType(array(), array(
'alpha' => 'text',
@@ -38,7 +39,7 @@ class FeedsMapperFieldTestCase extends FeedsMapperTestCase {
$this->setSettings('csv', NULL, array('content_type' => '', 'import_period' => FEEDS_SCHEDULE_NEVER));
$this->setPlugin('csv', 'FeedsFileFetcher');
$this->setPlugin('csv', 'FeedsCSVParser');
$this->setSettings('csv', 'FeedsNodeProcessor', array('content_type' => $typename));
$this->setSettings('csv', 'FeedsNodeProcessor', array('bundle' => $typename));
$this->addMappings('csv', array(
0 => array(
'source' => 'title',
@@ -87,4 +88,146 @@ class FeedsMapperFieldTestCase extends FeedsMapperTestCase {
$this->assertNodeFieldValue('gamma', '1.20');
$this->assertNodeFieldValue('delta', '5.62951');
}
/**
* Tests if values are cleared out when an empty value is provided.
*/
public function testClearOutValues() {
// Create content type.
$typename = $this->createContentType(array(), array(
'alpha' => 'text',
'beta' => 'number_integer',
'gamma' => 'number_decimal',
'delta' => 'number_float',
));
// Create and configure importer.
$this->createImporterConfiguration('Content CSV', 'csv');
$this->setSettings('csv', NULL, array('content_type' => '', 'import_period' => FEEDS_SCHEDULE_NEVER));
$this->setPlugin('csv', 'FeedsFileFetcher');
$this->setPlugin('csv', 'FeedsCSVParser');
$this->setSettings('csv', 'FeedsNodeProcessor', array('bundle' => $typename, 'update_existing' => 1));
$this->addMappings('csv', array(
array(
'source' => 'guid',
'target' => 'guid',
'unique' => TRUE,
),
array(
'source' => 'title',
'target' => 'title',
),
array(
'source' => 'created',
'target' => 'created',
),
array(
'source' => 'body',
'target' => 'body',
),
array(
'source' => 'alpha',
'target' => 'field_alpha',
),
array(
'source' => 'beta',
'target' => 'field_beta',
),
array(
'source' => 'gamma',
'target' => 'field_gamma',
),
array(
'source' => 'delta',
'target' => 'field_delta',
),
));
// Import CSV file.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content.csv');
$this->assertText('Created 2 nodes');
// Check the two imported nodes.
$this->drupalGet('node/1/edit');
$this->assertNodeFieldValue('alpha', 'Lorem');
$this->assertNodeFieldValue('beta', '42');
$this->assertNodeFieldValue('gamma', '4.20');
$this->assertNodeFieldValue('delta', '3.14159');
$this->assertFieldByName('body[und][0][value]', 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.');
$this->drupalGet('node/2/edit');
$this->assertNodeFieldValue('alpha', 'Ut wisi');
$this->assertNodeFieldValue('beta', '32');
$this->assertNodeFieldValue('gamma', '1.20');
$this->assertNodeFieldValue('delta', '5.62951');
$this->assertFieldByName('body[und][0][value]', 'Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.');
// Import CSV file with empty values.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_empty.csv');
$this->assertText('Updated 2 nodes');
// Check if all values were cleared out for node 1.
$this->drupalGet('node/1/edit');
$this->assertNoNodeFieldValue('alpha', 'Lorem');
$this->assertNoNodeFieldValue('beta', '42');
$this->assertNoNodeFieldValue('gamma', '4.20');
$this->assertNoNodeFieldValue('delta', '3.14159');
$this->assertFieldByName('body[und][0][value]', '');
// Check if labels for fields that should be cleared out are not shown.
$this->drupalGet('node/1');
$this->assertNoText('alpha_text_label');
$this->assertNoText('beta_number_integer_label');
$this->assertNoText('gamma_number_decimal_label');
$this->assertNoText('delta_number_float_label');
// Check if zero's didn't cleared out values for node 2.
$this->drupalGet('node/2/edit');
$this->assertNodeFieldValue('alpha', 0);
$this->assertNodeFieldValue('beta', 0);
$this->assertNodeFieldValue('gamma', 0);
$this->assertNodeFieldValue('delta', 0);
$this->assertFieldByName('body[und][0][value]', 0);
// Check if labels for fields of node 2 are still shown.
$this->drupalGet('node/2');
$this->assertText('alpha_text_label');
$this->assertText('beta_number_integer_label');
$this->assertText('gamma_number_decimal_label');
$this->assertText('delta_number_float_label');
// Re-import the first file again.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content.csv');
$this->assertText('Updated 2 nodes');
// Check if the two imported nodes have content again.
$this->drupalGet('node/1/edit');
$this->assertNodeFieldValue('alpha', 'Lorem');
$this->assertNodeFieldValue('beta', '42');
$this->assertNodeFieldValue('gamma', '4.20');
$this->assertNodeFieldValue('delta', '3.14159');
$this->assertFieldByName('body[und][0][value]', 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.');
$this->drupalGet('node/2/edit');
$this->assertNodeFieldValue('alpha', 'Ut wisi');
$this->assertNodeFieldValue('beta', '32');
$this->assertNodeFieldValue('gamma', '1.20');
$this->assertNodeFieldValue('delta', '5.62951');
$this->assertFieldByName('body[und][0][value]', 'Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.');
// Import CSV file with non-existent values.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_non_existent.csv');
$this->assertText('Updated 2 nodes');
// Check if all values were cleared out for node 1.
$this->drupalGet('node/1/edit');
$this->assertNoNodeFieldValue('alpha', 'Lorem');
$this->assertNoNodeFieldValue('beta', '42');
$this->assertNoNodeFieldValue('gamma', '4.20');
$this->assertNoNodeFieldValue('delta', '3.14159');
$this->assertFieldByName('body[und][0][value]', '');
// Check if labels for fields that should be cleared out are not shown.
$this->drupalGet('node/1');
$this->assertNoText('alpha_text_label');
$this->assertNoText('beta_number_integer_label');
$this->assertNoText('gamma_number_decimal_label');
$this->assertNoText('delta_number_float_label');
}
}

View File

@@ -2,17 +2,14 @@
/**
* @file
* Test case for Filefield mapper mappers/filefield.inc.
* Contains FeedsMapperFileTestCase.
*/
/**
* Class for testing Feeds file mapper.
*
* @todo Add a test for enclosures using a local file that is
* a) in place and that
* b) needs to be copied from one location to another.
* Test case for Filefield mapper mappers/filefield.inc.
*/
class FeedsMapperFileTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: File field',
@@ -21,16 +18,20 @@ class FeedsMapperFileTestCase extends FeedsMapperTestCase {
);
}
public function setUp() {
parent::setUp(array('dblog'));
}
/**
* Basic test loading a single entry CSV file.
*/
public function test() {
// If this is unset (or FALSE) http_request.inc will use curl, and will generate a 404
// for this feel url provided by feeds_tests. However, if feeds_tests was enabled in your
// site before running the test, it will work fine. Since it is truly screwy, lets just
// force it to use drupal_http_request for this test case.
// If this is unset (or FALSE) http_request.inc will use curl, and will
// generate a 404 for this feel url provided by feeds_tests. However, if
// feeds_tests was enabled in your site before running the test, it will
// work fine. Since it is truly screwy, lets just force it to use
// drupal_http_request for this test case.
variable_set('feeds_never_use_curl', TRUE);
variable_set('clean_url', TRUE);
// Only download simplepie if the plugin doesn't already exist somewhere.
// People running tests locally might have it.
@@ -40,40 +41,46 @@ class FeedsMapperFileTestCase extends FeedsMapperTestCase {
// Reset all the caches!
$this->resetAll();
}
$typename = $this->createContentType(array(), array('files' => 'file'));
$typename = $this->createContentType(array(), array(
'files' => array(
'type' => 'file',
'instance_settings' => array(
'instance[settings][file_extensions]' => 'png, gif, jpg, jpeg',
),
),
));
// 1) Test mapping remote resources to file field.
// Create importer configuration.
$this->createImporterConfiguration();
$this->setPlugin('syndication', 'FeedsSimplePieParser');
$this->setSettings('syndication', 'FeedsNodeProcessor', array('content_type' => $typename));
$this->setSettings('syndication', 'FeedsNodeProcessor', array('bundle' => $typename));
$this->addMappings('syndication', array(
0 => array(
'source' => 'title',
'target' => 'title'
'target' => 'title',
),
1 => array(
'source' => 'timestamp',
'target' => 'created'
'target' => 'created',
),
2 => array(
'source' => 'enclosures',
'target' => 'field_files'
'target' => 'field_files:uri',
),
));
$nid = $this->createFeedNode('syndication', $GLOBALS['base_url'] . '/testing/feeds/flickr.xml');
$this->assertText('Created 5 nodes');
$files = $this->_testFiles();
$files = $this->listTestFiles();
$entities = db_select('feeds_item')
->fields('feeds_item', array('entity_id'))
->condition('id', 'syndication')
->execute();
foreach ($entities as $entity) {
$this->drupalGet('node/' . $entity->entity_id . '/edit');
$f = new FeedsEnclosure(array_shift($files), NULL);
$this->assertText($f->getLocalValue());
$this->assertText(str_replace(' ', '_', array_shift($files)));
}
// 2) Test mapping local resources to file field.
@@ -90,39 +97,36 @@ class FeedsMapperFileTestCase extends FeedsMapperTestCase {
// Create a CSV importer configuration.
$this->createImporterConfiguration('Node import from CSV', 'node');
$this->setPlugin('node', 'FeedsCSVParser');
$this->setSettings('node', 'FeedsNodeProcessor', array('content_type' => $typename));
$this->setSettings('node', 'FeedsNodeProcessor', array('bundle' => $typename));
$this->setSettings('node', NULL, array('content_type' => ''));
$this->addMappings('node', array(
0 => array(
'source' => 'title',
'target' => 'title'
'target' => 'title',
),
1 => array(
'source' => 'file',
'target' => 'field_files'
'target' => 'field_files:uri',
),
));
$edit = array(
'content_type' => '',
);
$this->drupalPost('admin/structure/feeds/node/settings', $edit, 'Save');
// Import.
$edit = array(
'feeds[FeedsHTTPFetcher][source]' => $GLOBALS['base_url'] . '/testing/feeds/files.csv',
'feeds[FeedsHTTPFetcher][source]' => url('testing/feeds/files.csv', array('absolute' => TRUE)),
);
$this->drupalPost('import/node', $edit, 'Import');
$this->assertText('Created 5 nodes');
// Assert: files should be in resources/.
$files = $this->_testFiles();
$files = $this->listTestFiles();
$entities = db_select('feeds_item')
->fields('feeds_item', array('entity_id'))
->condition('id', 'node')
->execute();
foreach ($entities as $entity) {
$this->drupalGet('node/' . $entity->entity_id . '/edit');
$f = new FeedsEnclosure(array_shift($files), NULL);
$this->assertRaw('resources/' . $f->getUrlEncodedValue());
$this->assertRaw('resources/' . rawurlencode(array_shift($files)));
}
// 3) Test mapping of local resources, this time leave files in place.
@@ -140,41 +144,271 @@ class FeedsMapperFileTestCase extends FeedsMapperTestCase {
$this->assertText('Created 5 nodes');
// Assert: files should be in images/ now.
$files = $this->_testFiles();
$files = $this->listTestFiles();
$entities = db_select('feeds_item')
->fields('feeds_item', array('entity_id'))
->condition('id', 'node')
->execute();
foreach ($entities as $entity) {
$this->drupalGet('node/' . $entity->entity_id . '/edit');
$f = new FeedsEnclosure(array_shift($files), NULL);
$this->assertRaw('images/' . $f->getUrlEncodedValue());
$this->assertRaw('images/' . rawurlencode(array_shift($files)));
}
// Deleting all imported items will delete the files from the images/ dir.
// @todo: for some reason the first file does not get deleted.
// $this->drupalPost('import/node/delete-items', array(), 'Delete');
// foreach ($this->_testFiles() as $file) {
// $this->assertFalse(is_file("public://images/$file"));
// }
$this->drupalPost('import/node/delete-items', array(), 'Delete');
foreach ($this->listTestFiles() as $file) {
$this->assertFalse(is_file("public://images/$file"));
}
}
/**
* Tests mapping to an image field.
*/
public function testImages() {
variable_set('feeds_never_use_curl', TRUE);
$typename = $this->createContentType(array(), array('images' => 'image'));
// Enable title and alt mapping.
$edit = array(
'instance[settings][alt_field]' => 1,
'instance[settings][title_field]' => 1,
);
$this->drupalPost("admin/structure/types/manage/$typename/fields/field_images", $edit, t('Save settings'));
// Create a CSV importer configuration.
$this->createImporterConfiguration('Node import from CSV', 'image_test');
$this->setPlugin('image_test', 'FeedsCSVParser');
$this->setSettings('image_test', 'FeedsNodeProcessor', array('bundle' => $typename));
$this->setSettings('image_test', NULL, array('content_type' => ''));
$this->addMappings('image_test', array(
0 => array(
'source' => 'title',
'target' => 'title',
),
1 => array(
'source' => 'file',
'target' => 'field_images:uri',
),
2 => array(
'source' => 'title2',
'target' => 'field_images:title',
),
3 => array(
'source' => 'alt',
'target' => 'field_images:alt',
),
));
// Import.
$edit = array(
'feeds[FeedsHTTPFetcher][source]' => url('testing/feeds/files-remote.csv', array('absolute' => TRUE)),
);
$this->drupalPost('import/image_test', $edit, 'Import');
$this->assertText('Created 5 nodes');
// Assert files exist.
$files = $this->listTestFiles();
$entities = db_select('feeds_item')
->fields('feeds_item', array('entity_id'))
->condition('id', 'image_test')
->execute();
foreach ($entities as $i => $entity) {
$this->drupalGet('node/' . $entity->entity_id . '/edit');
$this->assertRaw(str_replace(' ', '_', array_shift($files)));
$this->assertRaw("Alt text $i");
$this->assertRaw("Title text $i");
}
}
public function testInvalidFileExtension() {
variable_set('feeds_never_use_curl', TRUE);
$typename = $this->createContentType(array(), array(
'files' => array(
'type' => 'file',
'instance_settings' => array(
'instance[settings][file_extensions]' => 'txt',
),
),
));
// Create a CSV importer configuration.
$this->createImporterConfiguration('Node import from CSV', 'invalid_extension');
$this->setPlugin('invalid_extension', 'FeedsCSVParser');
$this->setSettings('invalid_extension', 'FeedsNodeProcessor', array('bundle' => $typename));
$this->setSettings('invalid_extension', NULL, array('content_type' => ''));
$this->addMappings('invalid_extension', array(
0 => array(
'source' => 'title',
'target' => 'title',
),
1 => array(
'source' => 'file',
'target' => 'field_files:uri',
),
));
// Import.
$edit = array(
'feeds[FeedsHTTPFetcher][source]' => url('testing/feeds/files-remote.csv', array('absolute' => TRUE)),
);
$this->drupalPost('import/invalid_extension', $edit, 'Import');
$this->assertText('Created 5 nodes');
foreach (range(1, 5) as $nid) {
$node = node_load($nid);
$this->assertTrue(empty($node->field_files));
}
foreach ($this->listTestFiles() as $filename) {
$message = t('The file @file has an invalid extension.', array('@file' => $filename));
$this->assertTrue(db_query("SELECT 1 FROM {watchdog} WHERE message = :message", array(':message' => $message))->fetchField());
}
// Test that query string and fragments are removed.
$enclosure = new FeedsEnclosure('http://example.com/image.jpg?thing=stuff', 'text/plain');
$this->assertEqual($enclosure->getLocalValue(), 'image.jpg');
$enclosure = new FeedsEnclosure('http://example.com/image.jpg#stuff', 'text/plain');
$this->assertEqual($enclosure->getLocalValue(), 'image.jpg');
$enclosure = new FeedsEnclosure('http://example.com/image.JPG?thing=stuff#stuff', 'text/plain');
$this->assertEqual($enclosure->getLocalValue(), 'image.JPG');
}
/**
* Tests if values are cleared out when an empty value or no value
* is provided.
*/
public function testClearOutValues() {
variable_set('feeds_never_use_curl', TRUE);
$this->createContentType(array(), array('files' => 'file'));
$typename = $this->createContentType(array(), array(
'images' => 'image',
));
// Enable title and alt mapping.
$edit = array(
'instance[settings][alt_field]' => 1,
'instance[settings][title_field]' => 1,
);
$this->drupalPost("admin/structure/types/manage/$typename/fields/field_images", $edit, t('Save settings'));
// Create and configure importer.
$this->createImporterConfiguration('Content CSV', 'csv');
$this->setSettings('csv', NULL, array(
'content_type' => '',
'import_period' => FEEDS_SCHEDULE_NEVER,
));
$this->setPlugin('csv', 'FeedsCSVParser');
$this->setSettings('csv', 'FeedsNodeProcessor', array(
'bundle' => $typename,
'update_existing' => 1,
));
$this->addMappings('csv', array(
0 => array(
'source' => 'guid',
'target' => 'guid',
'unique' => TRUE,
),
1 => array(
'source' => 'title',
'target' => 'title',
),
2 => array(
'source' => 'file',
'target' => 'field_images:uri',
),
3 => array(
'source' => 'title2',
'target' => 'field_images:title',
),
4 => array(
'source' => 'alt',
'target' => 'field_images:alt',
),
));
// Import.
$edit = array(
'feeds[FeedsHTTPFetcher][source]' => url('testing/feeds/files-remote.csv', array('absolute' => TRUE)),
);
$this->drupalPost('import/csv', $edit, 'Import');
$this->assertText('Created 5 nodes');
// Assert files exist.
$files = $this->listTestFiles();
foreach ($files as $file) {
$file_path = drupal_realpath('public://') . '/' . str_replace(' ', '_', $file);
$this->assertTrue(file_exists($file_path), format_string('The file %file exists.', array(
'%file' => $file_path,
)));
}
// Assert files exists with the expected alt/title on node edit form.
$entities = db_select('feeds_item')
->fields('feeds_item', array('entity_id'))
->condition('id', 'csv')
->execute()
->fetchAll();
foreach ($entities as $i => $entity) {
$this->drupalGet('node/' . $entity->entity_id . '/edit');
$this->assertRaw(str_replace(' ', '_', array_shift($files)));
$this->assertRaw("Alt text $i");
$this->assertRaw("Title text $i");
}
// Import CSV with empty alt/title fields and check if these are removed.
$edit = array(
'feeds[FeedsHTTPFetcher][source]' => url('testing/feeds/files-empty-alt-title.csv', array('absolute' => TRUE)),
);
$this->drupalPost('import/csv', $edit, 'Import');
$this->assertText('Updated 5 nodes');
$files = $this->listTestFiles();
foreach ($entities as $i => $entity) {
$this->drupalGet('node/' . $entity->entity_id . '/edit');
$this->assertRaw(str_replace(' ', '_', array_shift($files)));
$this->assertNoRaw("Alt text $i");
$this->assertNoRaw("Title text $i");
}
// Import CSV with empty file fields and check if all files are removed.
$edit = array(
'feeds[FeedsHTTPFetcher][source]' => url('testing/feeds/files-empty.csv', array('absolute' => TRUE)),
);
$this->drupalPost('import/csv', $edit, 'Import');
$this->assertText('Updated 5 nodes');
// Assert files are removed.
$files = $this->listTestFiles();
foreach ($files as $file) {
$file_path = drupal_realpath('public://') . '/' . str_replace(' ', '_', $file);
$this->assertFalse(file_exists($file_path), format_string('The file %file no longer exists.', array(
'%file' => $file_path,
)));
}
// Check if the files are removed from the node edit form as well.
foreach ($entities as $i => $entity) {
$this->drupalGet('node/' . $entity->entity_id . '/edit');
$this->assertNoRaw(str_replace(' ', '_', array_shift($files)));
}
}
/**
* Lists test files.
*/
public function _testFiles() {
return array('tubing.jpeg', 'foosball.jpeg', 'attersee.jpeg', 'hstreet.jpeg', 'la fayette.jpeg');
protected function listTestFiles() {
return array(
'tubing.jpeg',
'foosball.jpeg',
'attersee.jpeg',
'hstreet.jpeg',
'la fayette.jpeg',
);
}
/**
* Handle file field widgets.
*/
public function selectFieldWidget($fied_name, $field_type) {
if ($field_type == 'file') {
return 'file_generic';
}
else {
return parent::selectFieldWidget($fied_name, $field_type);
}
}
}

View File

@@ -0,0 +1,245 @@
<?php
/**
* @file
* Contains FeedsMapperFormatConfig.
*/
/**
* Class for testing "Text format" mapping configuration on text fields.
*/
class FeedsMapperFormatConfig extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: Text format mapping configuration',
'description' => 'Test text format mapping configuration for text fields.',
'group' => 'Feeds',
);
}
public function setUp() {
parent::setUp(array('list', 'taxonomy'));
}
/**
* Basic test for setting mapping configuration.
*/
public function test() {
// Create content type with three fields. Two that support text formats
// and one that doesn't.
$typename = $this->createContentType(array(), array(
'alpha' => array(
'type' => 'text',
'instance_settings' => array(
'instance[settings][text_processing]' => 1,
),
),
'beta' => array(
'type' => 'text_long',
'instance_settings' => array(
'instance[settings][text_processing]' => 1,
),
),
'gamma' => array(
'type' => 'text',
'instance_settings' => array(
'instance[settings][text_processing]' => 0,
),
),
));
// Create a new filter format.
$format = drupal_strtolower($this->randomName());
$edit = array(
'format' => $format,
'name' => $this->randomName(),
// Authenticated users.
'roles[2]' => TRUE,
);
$this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
// Create and configure importer.
$this->createImporterConfiguration();
$this->setSettings('syndication', NULL, array('content_type' => ''));
$this->setPlugin('syndication', 'FeedsFileFetcher');
$this->setPlugin('syndication', 'FeedsCSVParser');
$this->setSettings('syndication', 'FeedsNodeProcessor', array('bundle' => $typename));
$this->addMappings('syndication', array(
0 => array(
'source' => 'title',
'target' => 'title',
),
1 => array(
'source' => 'created',
'target' => 'created',
),
2 => array(
'source' => 'body',
'target' => 'body',
'format' => $format,
),
3 => array(
'source' => 'alpha',
'target' => 'field_alpha',
'format' => $format,
),
4 => array(
'source' => 'beta',
'target' => 'field_beta',
'format' => $format,
),
5 => array(
'source' => 'gamma',
'target' => 'field_gamma',
),
));
// Assert that for the gamma field no format can be chosen.
$this->assertNoText('Text format: Plain text');
// Import csv file.
$this->importFile('syndication', $this->absolutePath() . '/tests/feeds/content.csv');
$this->assertText('Created 2 nodes');
// Assert that fields body, alpha and beta got the expected text format.
$node = node_load(1);
$this->assertEqual($format, $node->body[LANGUAGE_NONE][0]['format'], 'The body field got the expected format.');
$this->assertEqual($format, $node->field_alpha[LANGUAGE_NONE][0]['format'], 'The alpha field got the expected format.');
$this->assertEqual($format, $node->field_beta[LANGUAGE_NONE][0]['format'], 'The beta field got the expected format.');
$this->assertEqual(filter_fallback_format(), $node->field_gamma[LANGUAGE_NONE][0]['format'], 'The gama field got the expected format.');
}
/**
* Tests the filter formats a user has access to.
*/
public function testWithLimitedPrivileges() {
// Create content type with a field that uses a text format.
$typename = $this->createContentType(array(), array(
'alpha' => array(
'type' => 'text',
'instance_settings' => array(
'instance[settings][text_processing]' => 1,
),
),
));
// Create a new user with limited privileges.
$account = $this->drupalCreateUser(array('administer feeds'));
// Create filter format the user may use.
$format1 = drupal_strtolower($this->randomName());
$edit1 = array(
'format' => $format1,
'name' => $this->randomName(),
// Authenticated users.
'roles[2]' => TRUE,
);
$this->drupalPost('admin/config/content/formats/add', $edit1, t('Save configuration'));
// Create filter format the user may NOT use.
$rid = $this->drupalCreateRole(array());
$format2 = drupal_strtolower($this->randomName());
$edit2 = array(
'format' => $format2,
'name' => $this->randomName(),
'roles[' . $rid . ']' => TRUE,
);
$this->drupalPost('admin/config/content/formats/add', $edit2, t('Save configuration'));
// Login as the user that may only use certain formats.
$this->drupalLogin($account);
// Create importer and ensure the user can use the first format.
$this->createImporterConfiguration();
$this->setSettings('syndication', NULL, array(
'content_type' => '',
'import_period' => FEEDS_SCHEDULE_NEVER,
));
$this->setPlugin('syndication', 'FeedsFileFetcher');
$this->setPlugin('syndication', 'FeedsCSVParser');
$this->setSettings('syndication', 'FeedsNodeProcessor', array('bundle' => $typename));
$this->addMappings('syndication', array(
0 => array(
'source' => 'alpha',
'target' => 'field_alpha',
'format' => $format1,
),
));
// Check user can choose first, but not second format as an option.
$this->drupalPostAJAX(NULL, array(), 'mapping_settings_edit_0');
$xpath = $this->constructFieldXpath('name', 'config[0][settings][format]');
$fields = $this->xpath($xpath);
$field = reset($fields);
$format_options = $this->getAllOptions($field);
$format1_found = FALSE;
$format2_found = FALSE;
foreach ($format_options as $option) {
if ($option['value'] == $format1) {
$format1_found = TRUE;
}
if ($option['value'] == $format2) {
$format2_found = TRUE;
}
}
// Assert first format can be chosen.
$this->assertTrue($format1_found, format_string('Text format %format can be chosen.', array('%format' => $format1)));
// Assert second format can NOT be chosen.
$this->assertFalse($format2_found, format_string('Text format %format can NOT be chosen.', array('%format' => $format2)));
}
/**
* Tests if text format can be set for taxonomy descriptions.
*/
public function testTaxonomyDescriptionTextFormat() {
// Create a vocabulary.
$edit = array(
'name' => 'Tags',
'machine_name' => 'tags',
);
$this->drupalPost('admin/structure/taxonomy/add', $edit, 'Save');
// Create a new filter format.
$format = drupal_strtolower($this->randomName());
$edit = array(
'format' => $format,
'name' => $this->randomName(),
// Authenticated users.
'roles[2]' => TRUE,
);
$this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
// Create a taxonomy term importer.
$this->createImporterConfiguration();
$this->setSettings('syndication', NULL, array(
'content_type' => '',
'import_period' => FEEDS_SCHEDULE_NEVER,
));
$this->setPlugin('syndication', 'FeedsFileFetcher');
$this->setPlugin('syndication', 'FeedsCSVParser');
$this->setPlugin('syndication', 'FeedsTermProcessor');
$this->setSettings('syndication', 'FeedsTermProcessor', array('bundle' => 'tags'));
$this->addMappings('syndication', array(
0 => array(
'source' => 'title',
'target' => 'name',
),
1 => array(
'source' => 'body',
'target' => 'description',
'format' => $format,
),
));
// Import csv file.
$this->importFile('syndication', $this->absolutePath() . '/tests/feeds/content.csv');
$this->assertText('Created 2 terms');
// Assert that the term description got the expected text format.
$term = taxonomy_term_load(1);
$this->assertEqual($format, $term->format, 'The taxonomy term got the expected format.');
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* @file
* Contains FeedsMapperHookTestCase.
*/
/**
* Test case for the various callbacks implemented for mappers.
*/
class FeedsMapperHookTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: Hooks and callbacks',
'description' => 'Test case for the various callbacks implemented for mappers.',
'group' => 'Feeds',
);
}
/**
* Basic test loading a double entry CSV file.
*/
public function test() {
// Create and configure importer.
$this->createImporterConfiguration();
$this->addMappings('syndication', array(
0 => array(
'source' => 'title',
'target' => 'title',
),
1 => array(
'source' => 'description',
'target' => 'test_target',
),
));
// Checks that alter hooks are invoked.
$this->assertText(t('The target description was altered.'));
// Inherently tests preprocess callbacks.
// @see feeds_tests_mapper_set_target()
$nid = $this->createFeedNode();
$this->drupalGet('node/2/edit');
$body_value = $this->xpath('//*[@name = "body[und][0][value]"]');
$value = unserialize((string) $body_value[0]);
$this->assertTrue(!empty($value));
// Tests old-style target keys.
$this->addMappings('syndication', array(
2 => array(
'source' => 'url',
'target' => 'test_target_compat',
),
));
// Click gear to get form.
$this->drupalPostAJAX(NULL, array(), 'mapping_settings_edit_2');
// Set some settings.
$edit = array(
'config[2][settings][checkbox]' => 1,
'config[2][settings][textfield]' => 'Some text',
'config[2][settings][textarea]' => 'Textarea value: Didery dofffffffffffffffffffffffffffffffffffff',
'config[2][settings][radios]' => 'option1',
'config[2][settings][select]' => 'option4',
);
$this->drupalPostAJAX(NULL, $edit, 'mapping_settings_update_2');
$this->assertText(t('* Changes made to target configuration are stored temporarily. Click Save to make your changes permanent.'));
}
}

View File

@@ -2,13 +2,28 @@
/**
* @file
* Test case for CCK link mapper mappers/date.inc.
* Contains FeedsMapperLinkTestCase.
*/
/**
* Class for testing Feeds <em>link</em> mapper.
* Test case for CCK link mapper mappers/date.inc.
*/
class FeedsMapperLinkTestCase extends FeedsMapperTestCase {
/**
* Title for link fields with a static title.
*
* @var string
*/
private $staticTitle;
/**
* Name of created content type.
*
* @var string
*/
private $contentType;
public static function getInfo() {
return array(
'name' => 'Mapper: Link',
@@ -20,16 +35,11 @@ class FeedsMapperLinkTestCase extends FeedsMapperTestCase {
public function setUp() {
parent::setUp(array('link'));
}
/**
* Basic test loading a single entry CSV file.
*/
public function test() {
$static_title = $this->randomName();
$this->staticTitle = $this->randomName();
// Create content type.
$typename = $this->createContentType(array(), array(
$this->contentType = $this->createContentType(array(), array(
'alpha' => array(
'type' => 'link_field',
'instance_settings' => array(
@@ -52,14 +62,19 @@ class FeedsMapperLinkTestCase extends FeedsMapperTestCase {
'type' => 'link_field',
'instance_settings' => array(
'instance[settings][title]' => 'value',
'instance[settings][title_value]' => $static_title,
'instance[settings][title_value]' => $this->staticTitle,
),
),
));
}
/**
* Basic test loading a single entry CSV file.
*/
public function test() {
// Create importer configuration.
$this->createImporterConfiguration(); //Create a default importer configuration
$this->setSettings('syndication', 'FeedsNodeProcessor', array('content_type' => $typename)); //Processor settings
$this->setSettings('syndication', 'FeedsNodeProcessor', array('bundle' => $this->contentType)); //Processor settings
$this->addMappings('syndication', array(
0 => array(
'source' => 'title',
@@ -112,12 +127,193 @@ class FeedsMapperLinkTestCase extends FeedsMapperTestCase {
$this->assertNodeFieldValue('alpha', array('url' => $url, 'static' => $title));
$this->assertNodeFieldValue('beta', array('url' => $url));
$this->assertNodeFieldValue('gamma', array('url' => $url, 'static' => $title));
$this->assertNodeFieldValue('omega', array('url' => $url, 'static' => $static_title));
$this->assertNodeFieldValue('omega', array('url' => $url, 'static' => $this->staticTitle));
// Test the static title.
$this->drupalGet('node/2');
$this->assertText($static_title, 'Static title link found.');
$this->assertText($this->staticTitle, 'Static title link found.');
}
/**
* Tests if values are cleared out when an empty value or no value
* is provided.
*/
public function testClearOutValues() {
// Create and configure importer.
$this->createImporterConfiguration('Content CSV', 'csv');
$this->setSettings('csv', NULL, array(
'content_type' => '',
'import_period' => FEEDS_SCHEDULE_NEVER,
));
$this->setPlugin('csv', 'FeedsFileFetcher');
$this->setPlugin('csv', 'FeedsCSVParser');
$this->setSettings('csv', 'FeedsNodeProcessor', array(
'bundle' => $this->contentType,
'update_existing' => 1,
));
$this->addMappings('csv', array(
0 => array(
'source' => 'guid',
'target' => 'guid',
'unique' => TRUE,
),
1 => array(
'source' => 'title',
'target' => 'title'
),
2 => array(
'source' => 'url',
'target' => 'field_alpha:url'
),
3 => array(
'source' => 'link_title',
'target' => 'field_alpha:title'
),
4 => array(
'source' => 'url',
'target' => 'field_beta:url'
),
5 => array(
'source' => 'link_title',
'target' => 'field_beta:title'
),
6 => array(
'source' => 'url',
'target' => 'field_gamma:url'
),
7 => array(
'source' => 'link_title',
'target' => 'field_gamma:title'
),
8 => array(
'source' => 'url',
'target' => 'field_omega:url'
),
9 => array(
'source' => 'link_title',
'target' => 'field_omega:title'
),
));
// Import CSV file.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_link.csv');
$this->assertText('Created 2 nodes');
// Check the imported nodes.
$link_values = array(
1 => array(
'title' => 'Feeds',
'url' => 'https://www.drupal.org/project/feeds',
),
2 => array(
'title' => 'Framework for expected behavior when importing empty/blank values',
'url' => 'https://www.drupal.org/node/1107522',
),
);
for ($i = 1; $i <= 2; $i++) {
$this->drupalGet("node/$i/edit");
$this->assertNodeFieldValue('alpha', array(
'url' => $link_values[$i]['url'],
'title' => $link_values[$i]['title'],
));
$this->assertNodeFieldValue('beta', array(
'url' => $link_values[$i]['url'],
));
$this->assertNodeFieldValue('gamma', array(
'url' => $link_values[$i]['url'],
'title' => $link_values[$i]['title'],
));
$this->assertNodeFieldValue('omega', array(
'url' => $link_values[$i]['url'],
));
// Test static title.
$this->drupalGet("node/$i");
$this->assertText($this->staticTitle, 'Static title link found.');
}
// Import CSV file with empty values.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_empty.csv');
$this->assertText('Updated 2 nodes');
// Check if all values were cleared out for both nodes.
for ($i = 1; $i <= 2; $i++) {
$this->drupalGet("node/$i/edit");
$this->assertNoNodeFieldValue('alpha', array(
'url' => $link_values[$i]['url'],
'title' => $link_values[$i]['title'],
));
$this->assertNoNodeFieldValue('beta', array(
'url' => $link_values[$i]['url'],
));
$this->assertNoNodeFieldValue('gamma', array(
'url' => $link_values[$i]['url'],
'title' => $link_values[$i]['title'],
));
$this->assertNoNodeFieldValue('omega', array(
'url' => $link_values[$i]['url'],
));
// Check labels.
$this->drupalGet('node/' . $i);
$this->assertNoText('alpha_link_field_label');
$this->assertNoText('beta_link_field_label');
$this->assertNoText('gamma_link_field_label');
$this->assertNoText('omega_link_field_label');
// Assert that the static title is no longer shown.
$this->assertNoText($this->staticTitle, 'Static title link not found.');
}
// Re-import the first file again and check if the values returned.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_link.csv');
$this->assertText('Updated 2 nodes');
for ($i = 1; $i <= 2; $i++) {
$this->drupalGet("node/$i/edit");
$this->assertNodeFieldValue('alpha', array(
'url' => $link_values[$i]['url'],
'title' => $link_values[$i]['title'],
));
$this->assertNodeFieldValue('beta', array(
'url' => $link_values[$i]['url'],
));
$this->assertNodeFieldValue('gamma', array(
'url' => $link_values[$i]['url'],
'title' => $link_values[$i]['title'],
));
$this->assertNodeFieldValue('omega', array(
'url' => $link_values[$i]['url'],
));
}
// Import CSV file with non-existent values.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_non_existent.csv');
$this->assertText('Updated 2 nodes');
// Check if all values were cleared out for node 1.
$this->drupalGet("node/1/edit");
$this->assertNoNodeFieldValue('alpha', array(
'url' => $link_values[1]['url'],
'title' => $link_values[1]['title'],
));
$this->assertNoNodeFieldValue('beta', array(
'url' => $link_values[1]['url'],
));
$this->assertNoNodeFieldValue('gamma', array(
'url' => $link_values[1]['url'],
'title' => $link_values[1]['title'],
));
$this->assertNoNodeFieldValue('omega', array(
'url' => $link_values[1]['url'],
));
$this->drupalGet('node/1');
$this->assertNoText('alpha_link_field_label');
$this->assertNoText('beta_link_field_label');
$this->assertNoText('gamma_link_field_label');
$this->assertNoText('omega_link_field_label');
// Assert that the static title is no longer shown.
$this->assertNoText($this->staticTitle, 'Static title link not found.');
}
/**
@@ -154,4 +350,5 @@ class FeedsMapperLinkTestCase extends FeedsMapperTestCase {
return parent::getFormFieldsValues($field_name, $index);
}
}
}

View File

@@ -0,0 +1,180 @@
<?php
/**
* @file
* Contains FeedsMapperListTestCase.
*/
/**
* Test case for List field mappers in mappers/list.inc
*/
class FeedsMapperListTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: List and Boolean',
'description' => 'Test Feeds Mapper support for List and Boolean fields.',
'group' => 'Feeds',
'dependencies' => array('list'),
);
}
public function setUp() {
parent::setUp(array('list'));
}
/**
* Tests if values are cleared out when an empty value is provided.
*/
public function testClearOutValues() {
// Create content type.
$typename = $this->createContentType(array(), array(
'alpha' => array(
'type' => 'list_text',
'settings' => array(
'field[settings][allowed_values]' => "0\nLorem\nUt wisi",
),
),
'beta' => array(
'type' => 'list_integer',
'settings' => array(
'field[settings][allowed_values]' => "0\n42\n32",
),
),
'delta' => array(
'type' => 'list_float',
'settings' => array(
'field[settings][allowed_values]' => "0\n3.14159\n5.62951",
),
),
'epsilon' => 'list_boolean',
));
// Create and configure importer.
$this->createImporterConfiguration('Content CSV', 'csv');
$this->setSettings('csv', NULL, array(
'content_type' => '',
'import_period' => FEEDS_SCHEDULE_NEVER,
));
$this->setPlugin('csv', 'FeedsFileFetcher');
$this->setPlugin('csv', 'FeedsCSVParser');
$this->setSettings('csv', 'FeedsNodeProcessor', array(
'bundle' => $typename,
'update_existing' => 1
));
$this->addMappings('csv', array(
array(
'source' => 'guid',
'target' => 'guid',
'unique' => TRUE,
),
array(
'source' => 'title',
'target' => 'title',
),
array(
'source' => 'alpha',
'target' => 'field_alpha',
),
array(
'source' => 'beta',
'target' => 'field_beta',
),
array(
'source' => 'delta',
'target' => 'field_delta',
),
array(
'source' => 'epsilon',
'target' => 'field_epsilon',
),
));
// Import CSV file.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content.csv');
$this->assertText('Created 2 nodes');
// Check the two imported nodes.
$this->drupalGet('node/1/edit');
$this->assertOptionSelected('edit-field-alpha-und', 'Lorem');
$this->assertOptionSelected('edit-field-beta-und', '42');
$this->assertOptionSelected('edit-field-delta-und', '3.14159');
$this->assertFieldChecked('edit-field-epsilon-und');
$this->drupalGet('node/2/edit');
$this->assertOptionSelected('edit-field-alpha-und', 'Ut wisi');
$this->assertOptionSelected('edit-field-beta-und', '32');
$this->assertOptionSelected('edit-field-delta-und', '5.62951');
$this->assertNoFieldChecked('edit-field-epsilon-und');
// Import CSV file with empty values.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_empty.csv');
$this->assertText('Updated 2 nodes');
// Check if all values were cleared out for node 1.
$this->drupalGet('node/1/edit');
$this->assertNoOptionSelected('edit-field-alpha-und', 'Lorem');
$this->assertNoOptionSelected('edit-field-beta-und', '42');
$this->assertNoOptionSelected('edit-field-delta-und', '3.14159');
$this->assertNoFieldChecked('edit-field-epsilon-und');
// Check if labels for fields that should be cleared out are not shown.
$this->drupalGet('node/1');
$this->assertNoText('alpha_list_text_label');
$this->assertNoText('beta_list_integer_label');
$this->assertNoText('delta_list_float_label');
$this->assertNoText('epsilon_list_boolean_label');
// Load node 1 and check if the boolean field does *not* have a value.
$node = node_load(1, NULL, TRUE);
$this->assertTrue(empty($node->field_epsilon[LANGUAGE_NONE]), 'The field field_epsilon is empty.');
// Check if zero's didn't cleared out values for node 2.
$this->drupalGet('node/2/edit');
$this->assertOptionSelected('edit-field-alpha-und', '0');
$this->assertOptionSelected('edit-field-beta-und', '0');
$this->assertOptionSelected('edit-field-delta-und', '0');
$this->assertNoFieldChecked('edit-field-epsilon-und');
// Check if labels for fields of node 2 are still shown.
$this->drupalGet('node/2');
$this->assertText('alpha_list_text_label');
$this->assertText('beta_list_integer_label');
$this->assertText('delta_list_float_label');
$this->assertText('epsilon_list_boolean_label');
// Load node 2 and check if the boolean field *does* have a value.
$node = node_load(2, NULL, TRUE);
$this->assertEqual('0', $node->field_epsilon[LANGUAGE_NONE][0]['value']);
// Re-import the first file again.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content.csv');
$this->assertText('Updated 2 nodes');
// Check if the two imported nodes have content again.
$this->drupalGet('node/1/edit');
$this->assertOptionSelected('edit-field-alpha-und', 'Lorem');
$this->assertOptionSelected('edit-field-beta-und', '42');
$this->assertOptionSelected('edit-field-delta-und', '3.14159');
$this->assertFieldChecked('edit-field-epsilon-und');
$this->drupalGet('node/2/edit');
$this->assertOptionSelected('edit-field-alpha-und', 'Ut wisi');
$this->assertOptionSelected('edit-field-beta-und', '32');
$this->assertOptionSelected('edit-field-delta-und', '5.62951');
$this->assertNoFieldChecked('edit-field-epsilon-und');
// Import CSV file with non-existent values.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_non_existent.csv');
$this->assertText('Updated 2 nodes');
// Check if all values were cleared out for node 1.
$this->drupalGet('node/1/edit');
$this->assertNoOptionSelected('edit-field-alpha-und', 'Lorem');
$this->assertNoOptionSelected('edit-field-beta-und', '42');
$this->assertNoOptionSelected('edit-field-delta-und', '3.14159');
$this->assertNoFieldChecked('edit-field-epsilon-und');
// Check if labels for fields that should be cleared out are not shown.
$this->drupalGet('node/1');
$this->assertNoText('alpha_list_text_label');
$this->assertNoText('beta_list_integer_label');
$this->assertNoText('delta_list_float_label');
$this->assertNoText('epsilon_list_boolean_label');
// Load node 1 and check if the boolean field does *not* have a value.
$node = node_load(1, NULL, TRUE);
$this->assertTrue(empty($node->field_epsilon[LANGUAGE_NONE]), 'The field field_epsilon is empty.');
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,13 +2,14 @@
/**
* @file
* Test case for path alias mapper path.inc.
* Contains FeedsMapperPathTestCase.
*/
/**
* Class for testing Feeds <em>path</em> mapper.
* Test case for path alias mapper path.inc.
*/
class FeedsMapperPathTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: Path',
@@ -25,7 +26,6 @@ class FeedsMapperPathTestCase extends FeedsMapperTestCase {
* Basic test loading a single entry CSV file.
*/
public function testNodeAlias() {
// Create importer configuration.
$this->createImporterConfiguration($this->randomName(), 'path_test');
$this->setPlugin('path_test', 'FeedsFileFetcher');
@@ -80,7 +80,6 @@ class FeedsMapperPathTestCase extends FeedsMapperTestCase {
* Test support for term aliases.
*/
public function testTermAlias() {
// Create importer configuration.
$this->createImporterConfiguration($this->randomName(), 'path_test');
$this->setPlugin('path_test', 'FeedsFileFetcher');
@@ -94,10 +93,7 @@ class FeedsMapperPathTestCase extends FeedsMapperTestCase {
);
$this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
$this->setSettings('path_test', 'FeedsTermProcessor', array('vocabulary' => 'addams'));
// Turn on update existing.
$this->setSettings('path_test', 'FeedsTermProcessor', array('update_existing' => 2));
$this->setSettings('path_test', 'FeedsTermProcessor', array('bundle' => 'addams', 'update_existing' => 2));
// Add mappings.
$this->addMappings('path_test', array(
@@ -158,6 +154,7 @@ class FeedsMapperPathTestCase extends FeedsMapperTestCase {
* Class for testing Feeds <em>path</em> mapper with pathauto.module.
*/
class FeedsMapperPathPathautoTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: Path with pathauto',
@@ -175,7 +172,6 @@ class FeedsMapperPathPathautoTestCase extends FeedsMapperTestCase {
* Basic for allowing pathauto to override the alias.
*/
public function test() {
// Create importer configuration.
$this->createImporterConfiguration($this->randomName(), 'path_test');
$this->setPlugin('path_test', 'FeedsFileFetcher');
@@ -208,7 +204,7 @@ class FeedsMapperPathPathautoTestCase extends FeedsMapperTestCase {
$aliases = array();
for ($i = 1; $i <= 9; $i++) {
$aliases[] = "path$i";
$aliases[] = "content/pathauto$i";
}
$this->assertAliasCount($aliases);
@@ -229,12 +225,8 @@ class FeedsMapperPathPathautoTestCase extends FeedsMapperTestCase {
}
public function assertAliasCount($aliases) {
$in_db = db_select('url_alias', 'a')
->fields('a')
->condition('a.alias', $aliases)
->execute()
->fetchAll();
$in_db = db_query("SELECT * FROM {url_alias} WHERE alias IN (:aliases)", array(':aliases' => $aliases))->fetchAll();
$this->assertEqual(count($in_db), count($aliases), 'Correct number of aliases in db.');
}
}

View File

@@ -2,13 +2,14 @@
/**
* @file
* Test suite for profile mapper mappers/profile.inc.
* Contains FeedsMapperProfileTestCase.
*/
/**
* Class for testing Feeds profile mapper.
* Test suite for profile mapper mappers/profile.inc.
*/
class FeedsMapperProfileTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: Profile',
@@ -17,16 +18,15 @@ class FeedsMapperProfileTestCase extends FeedsMapperTestCase {
);
}
function setUp() {
public function setUp() {
// Call parent setup with required modules.
parent::setUp(array('profile'));
}
/**
* Basic test loading a doulbe entry CSV file.
* Basic test loading a double entry CSV file.
*/
function test() {
public function test() {
// Create profile fields.
$edit = array(
'category' => 'test',
@@ -99,4 +99,5 @@ class FeedsMapperProfileTestCase extends FeedsMapperTestCase {
$this->assertEqual($account->profile_textfield_test, 'blue', 'User profile_textfield_test is correct');
$this->assertEqual($account->profile_select_test, 'beta', 'User profile_select_test is correct');
}
}

View File

@@ -0,0 +1,210 @@
<?php
/**
* @file
* Contains FeedsMapperNodeSummaryTestCase.
*/
/**
* Test case for mapping to node summary.
*/
class FeedsMapperNodeSummaryTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: Text with summary',
'description' => 'Test Feeds Mapper support for text with summary fields.',
'group' => 'Feeds',
);
}
/**
* Tests importing CSV files for text fields with summary.
*/
public function test() {
// Create and configure importer.
$this->createImporterWithSummaryMapper();
// Create a new filter format.
$format = drupal_strtolower($this->randomName());
$edit = array(
'format' => $format,
'name' => $this->randomName(),
// Authenticated users.
'roles[2]' => TRUE,
);
$this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
// The "update existing" and "skip hash check" are turned on so we can test
// later if the summaries of the nodes get overwritten with the values from
// the source.
$this->setSettings('syndication', 'FeedsNodeProcessor', array(
'update_existing' => 2,
'skip_hash_check' => TRUE,
'input_format' => $format,
));
// Import CSV file.
$this->importFile('syndication', $this->absolutePath() . '/tests/feeds/node_summary.csv');
$this->assertText('Created 3 nodes');
$this->assertNodeSummaryValues();
// Check that text format is applied correctly.
$this->drupalGet('node/1/edit');
$this->assertNodeFieldValue('format', $format);
// Check the teasers of the three imported nodes, assumed to be all present
// on the front page.
$this->assertNodeTeaserValues();
// Set a summary and a text for each imported node.
$edit = array(
'body[und][0][summary]' => 'Nam liber tempor summary',
'body[und][0][value]' => 'Nam liber tempor body',
);
$this->drupalPost('node/1/edit', $edit, t('Save'));
$this->drupalPost('node/2/edit', $edit, t('Save'));
$this->drupalPost('node/3/edit', $edit, t('Save'));
// Import the same CSV file again.
$this->importFile('syndication', $this->absolutePath() . '/tests/feeds/node_summary.csv');
$this->assertText('Updated 3 nodes');
$this->assertNodeSummaryValues();
$this->assertNodeTeaserValues();
// The previous texts of the nodes should no longer be visible.
$this->assertNoText('Nam liber tempor summary');
$this->assertNoText('Nam liber tempor body');
// Check that text format is applied correctly.
$this->drupalGet('node/1/edit');
$this->assertNodeFieldValue('format', $format);
$this->drupalGet('node/2/edit');
$this->assertNodeFieldValue('format', $format);
$this->drupalGet('node/3/edit');
$this->assertNodeFieldValue('format', $format);
// Remove the body mapping to check that the text format doesn't get updated
// from the summary.
$this->removeMappings('syndication', array(
2 => array(
'source' => 'body',
'target' => 'body',
),
));
// Change the text format and remove the body mapping to ensure that the
// text format doesn't change.
$this->setSettings('syndication', 'FeedsNodeProcessor', array(
'input_format' => 'plain_text',
));
$this->importFile('syndication', $this->absolutePath() . '/tests/feeds/node_summary.csv');
$this->assertText('Updated 3 nodes');
// Check that text format remains at its previous value.
$this->drupalGet('node/1/edit');
$this->assertNodeFieldValue('format', $format);
$this->drupalGet('node/2/edit');
$this->assertNodeFieldValue('format', $format);
$this->drupalGet('node/3/edit');
$this->assertNodeFieldValue('format', $format);
}
/**
* Creates an importer with a summary mapper.
*
* @param $name
* The natural name of the feed.
* @param $id
* The persistent id of the feed.
*
* @return void
*/
protected function createImporterWithSummaryMapper($name = 'Syndication', $id = 'syndication') {
// Create content type. A field named "body" which is of type "Long text and summary"
// will be created by default, so we don't need to create a field of that type here.
$typename = $this->createContentType(array());
// Create and configure importer.
$this->createImporterConfiguration($name, $id);
$this->setSettings('syndication', NULL, array(
'content_type' => '',
'import_period' => FEEDS_SCHEDULE_NEVER,
));
$this->setPlugin('syndication', 'FeedsFileFetcher');
$this->setPlugin('syndication', 'FeedsCSVParser');
$this->setSettings('syndication', 'FeedsNodeProcessor', array('bundle' => $typename));
$this->addMappings('syndication', array(
0 => array(
'source' => 'title',
'target' => 'title',
),
1 => array(
'source' => 'summary',
'target' => 'body:summary',
),
2 => array(
'source' => 'body',
'target' => 'body',
),
3 => array(
'source' => 'guid',
'target' => 'guid',
'unique' => TRUE,
),
));
}
/**
* Overrides FeedsMapperTestCase::getFormFieldsNames().
*
* Returns different form field names for:
* - body
* This field doesn't have the "field_" prefix.
* - summary
* Which is part of the body field.
* - format
* The format of the body field.
*/
protected function getFormFieldsNames($field_name, $index) {
switch ($field_name) {
case 'body':
return array("body[und][{$index}][value]");
case 'summary':
return array("body[und][{$index}][summary]");
case 'format':
return array("body[und][{$index}][format]");
}
return parent::getFormFieldsNames($field_name, $index);
}
/**
* Checks that the nodes match the imported values.
*/
protected function assertNodeSummaryValues() {
// Check the three imported nodes.
$this->drupalGet('node/1/edit');
$this->assertNodeFieldValue('summary', 'Lorem ipsum summary');
$this->assertNodeFieldValue('body', 'Lorem ipsum body');
$this->drupalGet('node/2/edit');
$this->assertNodeFieldValue('summary', '');
$this->assertNodeFieldValue('body', 'Ut wisi enim ad minim veniam body');
$this->drupalGet('node/3/edit');
$this->assertNodeFieldValue('summary', '');
$this->assertNodeFieldValue('body', '');
}
/**
* Checks the frontpage for teaser values.
*/
protected function assertNodeTeaserValues() {
$this->drupalGet('');
$this->assertText('Lorem ipsum summary');
$this->assertNoText('Lorem ipsum body');
$this->assertText('Ut wisi enim ad minim veniam body');
}
}

View File

@@ -2,13 +2,14 @@
/**
* @file
* Test case for taxonomy mapper mappers/taxonomy.inc.
* Contains FeedsMapperTaxonomyTestCase.
*/
/**
* Class for testing Feeds <em>content</em> mapper.
* Test case for taxonomy mapper mappers/taxonomy.inc.
*/
class FeedsMapperTaxonomyTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Mapper: Taxonomy',
@@ -17,7 +18,7 @@ class FeedsMapperTaxonomyTestCase extends FeedsMapperTestCase {
);
}
function setUp() {
public function setUp() {
parent::setUp();
// Add Tags vocabulary
@@ -112,10 +113,9 @@ class FeedsMapperTaxonomyTestCase extends FeedsMapperTestCase {
}
/**
* Test inheriting taxonomy from the feed node.
* Tests inheriting taxonomy from the feed node.
*/
function testInheritTaxonomy() {
public function testInheritTaxonomy() {
// Adjust importer settings
$this->setSettings('syndication', NULL, array('import_period' => FEEDS_SCHEDULE_NEVER));
$this->setSettings('syndication', NULL, array('import_on_create' => FALSE));
@@ -152,120 +152,327 @@ class FeedsMapperTaxonomyTestCase extends FeedsMapperTestCase {
}
/**
* Test aggregating RSS categories to taxonomy.
* Tests searching taxonomy terms by name.
*/
/*
function testRSSCategoriesToTaxonomy() {
// Add mapping to tags vocabulary.
$this->addMappings('syndication',
array(
array(
'source' => 'tags',
'target' => 'taxonomy:1',
),
)
);
// Aggregate feed node with "Tag" vocabulary.
$nid = $this->createFeedNode();
// Assert 10 items aggregated after creation of the node.
$this->assertText('Created 10 nodes');
// There should be 30 terms and 44 term-node relations.
$this->assertEqual(30, db_query("SELECT count(*) FROM {term_data}")->fetchField(), "Found correct number of terms.");
$this->assertEqual(44, db_query("SELECT count(*) FROM {term_node}")->fetchField(), "Found correct number of term-node relations.");
// Take a look at the actual terms on frontpage.
$this->drupalGet('node');
public function testSearchByName() {
$terms = array(
'authentication',
'custom mapping',
'data visualization',
'Drupal',
'Drupal planet',
'faceted search',
'GeoDC',
'graphs',
'interface',
'intranet',
'localization',
'localization client',
'localization server',
'map-basec browser',
'mapbox',
'microfinance',
'MIX Market',
'open atrium',
'open data',
'open source',
'Peru',
'salesforce',
'siteminder',
'siteminder module',
'software freedom day',
'translation',
'translation server',
'usability',
'Washington DC',
'World Bank',
'Drupal planet',
);
$this->setSettings('syndication', 'FeedsNodeProcessor', array(
'skip_hash_check' => TRUE,
'update_existing' => 2,
));
$mappings = array(
5 => array(
'source' => 'tags',
'target' => 'field_tags',
'term_search' => 0,
),
);
$this->addMappings('syndication', $mappings);
$nid = $this->createFeedNode('syndication', NULL, 'Syndication');
$this->assertText('Created 10 nodes.');
// Check that terms we not auto-created.
$this->drupalGet('node/2');
foreach ($terms as $term) {
$this->assertNoTaxonomyTerm($term);
}
$this->drupalGet('node/3');
$this->assertNoTaxonomyTerm('Washington DC');
// Change the mapping configuration.
$this->removeMappings('syndication', $mappings);
// Turn on autocreate.
$mappings[5]['autocreate'] = TRUE;
$this->addMappings('syndication', $mappings);
$this->drupalPost('node/' . $nid . '/import', array(), t('Import'));
$this->assertText('Updated 10 nodes.');
$this->drupalGet('node/2');
foreach ($terms as $term) {
$this->assertTaxonomyTerm($term);
}
$this->drupalGet('node/3');
$this->assertTaxonomyTerm('Washington DC');
// Delete all items, all associations are gone.
$this->drupalPost("node/$nid/delete-items", array(), 'Delete');
$this->assertText('Deleted 10 nodes');
$this->assertEqual(30, db_query("SELECT count(*) FROM {term_data}")->fetchField(), "Found correct number of terms.");
$this->assertEqual(0, db_query("SELECT count(*) FROM {term_node}")->fetchField(), "Found correct number of term-node relations.");
$names = db_query('SELECT name FROM {taxonomy_term_data}')->fetchCol();
$this->assertEqual(count($names), 31, 'Found correct number of terms in the database.');
// Remove "Tag" setting, import again.
$edit = array(
'tags' => FALSE,
);
$this->drupalPost('admin/content/taxonomy/edit/vocabulary/1', $edit, 'Save');
$this->drupalPost("node/$nid/import", array(), 'Import');
$this->assertText('Created 10 nodes');
// We should only get one term-node association per node.
$this->assertEqual(30, db_query("SELECT count(*) FROM {term_data}")->fetchField(), "Found correct number of terms.");
$this->assertEqual(10, db_query("SELECT count(*) FROM {term_node}")->fetchField(), "Found correct number of term-node relations.");
// Delete all items.
$this->drupalPost("node/$nid/delete-items", array(), 'Delete');
// Set vocabulary to multiple terms, import again.
$edit = array(
'multiple' => TRUE,
);
$this->drupalPost('admin/content/taxonomy/edit/vocabulary/1', $edit, 'Save');
$this->drupalPost("node/$nid/import", array(), 'Import');
$this->assertText('Created 10 nodes');
// We should get all term-node associations again.
$this->assertEqual(30, db_query("SELECT count(*) FROM {term_data}")->fetchField(), "Found correct number of terms.");
$this->assertEqual(44, db_query("SELECT count(*) FROM {term_node}")->fetchField(), "Found correct number of term-node relations.");
// Delete all items.
$this->drupalPost("node/$nid/delete-items", array(), 'Delete');
// Remove a term, import again.
$this->drupalPost('admin/content/taxonomy/edit/term/1', array(), 'Delete');
$this->drupalPost(NULL, array(), 'Delete');
$this->assertText('Deleted term');
$this->drupalPost("node/$nid/import", array(), 'Import');
$this->assertText('Created 10 nodes');
// This term should now be missing from term-node associations.
$this->assertEqual(29, db_query("SELECT count(*) FROM {term_data}")->fetchField(), "Found correct number of terms.");
$this->assertEqual(39, db_query("SELECT count(*) FROM {term_node}")->fetchField(), "Found correct number of term-node relations.");
// Run import again. This verifys that the terms we found by name.
$this->drupalPost('node/' . $nid . '/import', array(), t('Import'));
$this->assertText('Updated 10 nodes.');
$names = db_query('SELECT name FROM {taxonomy_term_data}')->fetchCol();
$this->assertEqual(count($names), 31, 'Found correct number of terms in the database.');
}
*/
/**
* Helper, finds node style taxonomy term markup in DOM.
* Tests mapping to taxonomy terms by tid.
*/
public function testSearchByID() {
// Create 10 terms. The first one was created in setup.
$terms = array(1);
foreach (range(2, 10) as $i) {
$term = (object) array(
'name' => 'term' . $i,
'vid' => 1,
);
taxonomy_term_save($term);
$terms[] = $term->tid;
}
FeedsPlugin::loadMappers();
$entity = new stdClass();
$target = 'field_tags';
$mapping = array(
'term_search' => FEEDS_TAXONOMY_SEARCH_TERM_ID,
'language' => LANGUAGE_NONE,
);
$source = FeedsSource::instance('tmp', 0);
taxonomy_feeds_set_target($source, $entity, $target, $terms, $mapping);
$this->assertEqual(count($entity->field_tags[LANGUAGE_NONE]), 10);
// Test a second mapping with a bogus term id.
taxonomy_feeds_set_target($source, $entity, $target, array(1234), $mapping);
$this->assertEqual(count($entity->field_tags[LANGUAGE_NONE]), 10);
}
/**
* Tests mapping to a taxonomy term's guid.
*/
public function testSearchByGUID() {
// Create 10 terms. The first one was created in setup.
$tids = array(1);
foreach (range(2, 10) as $i) {
$term = (object) array(
'name' => 'term' . $i,
'vid' => 1,
);
taxonomy_term_save($term);
$tids[] = $term->tid;
}
// Create a bunch of bogus imported terms.
$guids = array();
foreach ($tids as $tid) {
$guid = 100 * $tid;
$guids[] = $guid;
$record = array(
'entity_type' => 'taxonomy_term',
'entity_id' => $tid,
'id' => 'does_not_exist',
'feed_nid' => 0,
'imported' => REQUEST_TIME,
'url' => '',
'guid' => $guid,
);
drupal_write_record('feeds_item', $record);
}
FeedsPlugin::loadMappers();
$entity = new stdClass();
$target = 'field_tags';
$mapping = array(
'term_search' => FEEDS_TAXONOMY_SEARCH_TERM_GUID,
'language' => LANGUAGE_NONE,
);
$source = FeedsSource::instance('tmp', 0);
taxonomy_feeds_set_target($source, $entity, $target, $guids, $mapping);
$this->assertEqual(count($entity->field_tags[LANGUAGE_NONE]), 10);
foreach ($entity->field_tags[LANGUAGE_NONE] as $delta => $values) {
$this->assertEqual($tids[$delta], $values['tid'], 'Correct term id foud.');
}
// Test a second mapping with a bogus term id.
taxonomy_feeds_set_target($source, $entity, $target, array(1234), $mapping);
$this->assertEqual(count($entity->field_tags[LANGUAGE_NONE]), 10);
foreach ($entity->field_tags[LANGUAGE_NONE] as $delta => $values) {
$this->assertEqual($tids[$delta], $values['tid'], 'Correct term id foud.');
}
}
/**
* Tests importing empty values
*/
public function testBlankSourceValues() {
// Create a CSV importer configuration.
$this->createImporterConfiguration('Node import from CSV', 'node');
$this->setPlugin('node', 'FeedsFileFetcher');
$this->setPlugin('node', 'FeedsCSVParser');
$this->setSettings('node', 'FeedsNodeProcessor', array('bundle' => 'article'));
$this->setSettings('node', NULL, array('content_type' => ''));
$this->addMappings('node', array(
0 => array(
'source' => 'title',
'target' => 'title',
),
1 => array(
'source' => 'tags',
'target' => 'field_tags',
'term_search' => 0,
'autocreate' => 1,
),
2 => array(
'source' => 'guid',
'target' => 'guid',
'unique' => TRUE,
),
));
// Verify that there are 5 nodes total.
$this->importFile('node', $this->absolutePath() . '/tests/feeds/taxonomy_empty_terms.csv');
$this->assertText('Created 5 nodes');
// Make sure only two terms were added
$names = db_query('SELECT name FROM {taxonomy_term_data}')->fetchCol();
$this->assertEqual(count($names), 2, 'Found correct number of terms in the database.');
// Make sure the correct terms were created
$terms = array(
'term1',
'0',
);
foreach ($terms as $term_name) {
$this->assertTrue(in_array($term_name, $names), 'Correct term created');
}
}
/**
* Tests that there are no errors when trying to map to an invalid vocabulary.
*/
public function testMissingVocabulary() {
$this->addMappings('syndication', array(
5 => array(
'source' => 'tags',
'target' => 'field_tags',
'term_search' => 0,
'autocreate' => TRUE,
),
));
// Create an invalid configuration.
db_delete('taxonomy_vocabulary')->execute();
$this->createFeedNode('syndication', NULL, 'Syndication');
$this->assertText('Created 10 nodes.');
}
/**
* Tests if values are cleared out when an empty value or no value
* is provided.
*/
public function testClearOutValues() {
// Create a CSV importer configuration.
$this->createImporterConfiguration('Node import from CSV', 'node');
$this->setSettings('node', NULL, array(
'content_type' => '',
));
$this->setPlugin('node', 'FeedsFileFetcher');
$this->setPlugin('node', 'FeedsCSVParser');
$this->setSettings('node', 'FeedsNodeProcessor', array(
'bundle' => 'article',
'update_existing' => 1,
));
$this->addMappings('node', array(
0 => array(
'source' => 'title',
'target' => 'title',
),
1 => array(
'source' => 'alpha',
'target' => 'field_tags',
'term_search' => 0,
'autocreate' => 1,
),
2 => array(
'source' => 'guid',
'target' => 'guid',
'unique' => TRUE,
),
));
$this->importFile('node', $this->absolutePath() . '/tests/feeds/content.csv');
$this->assertText('Created 2 nodes');
// Check the imported nodes.
$terms1 = taxonomy_get_term_by_name('Lorem');
$term1 = reset($terms1);
$terms2 = taxonomy_get_term_by_name('Ut wisi');
$term2 = reset($terms2);
$taxonomy_values = array(
1 => $term1->tid,
2 => $term2->tid,
);
for ($i = 1; $i <= 2; $i++) {
$this->drupalGet("node/$i/edit");
$this->assertFieldByName('field_tags[und][]', $taxonomy_values[$i]);
}
// Import CSV file with empty values.
$this->importFile('node', $this->absolutePath() . '/tests/feeds/content_empty.csv');
$this->assertText('Updated 2 nodes');
// Check if the taxonomy reference field was cleared out for node 1.
$this->drupalGet('node/1/edit');
$this->assertFieldByName('field_tags[und][]', '_none');
$this->drupalGet('node/1');
$this->assertNoText('field_tags');
// Check if zero's didn't cleared out the taxonomy reference field for
// node 2.
$terms0 = taxonomy_get_term_by_name('0');
$term0 = reset($terms0);
$this->drupalGet('node/2/edit');
$this->assertFieldByName('field_tags[und][]', $term0->tid);
$this->drupalGet('node/2');
$this->assertText('field_tags');
// Re-import the first file again and check if the values returned.
$this->importFile('node', $this->absolutePath() . '/tests/feeds/content.csv');
$this->assertText('Updated 2 nodes');
for ($i = 1; $i <= 2; $i++) {
$this->drupalGet("node/$i/edit");
$this->assertFieldByName('field_tags[und][]', $taxonomy_values[$i]);
}
// Import CSV file with non-existent values.
$this->importFile('node', $this->absolutePath() . '/tests/feeds/content_non_existent.csv');
$this->assertText('Updated 2 nodes');
// Check if the taxonomy reference field was cleared out for node 1.
$this->drupalGet('node/1/edit');
$this->assertFieldByName('field_tags[und][]', '_none');
$this->drupalGet('node/1');
$this->assertNoText('field_tags');
}
/**
* Finds node style taxonomy term markup in DOM.
*/
public function assertTaxonomyTerm($term) {
$term = check_plain($term);
$this->assertPattern('/<a href="\/.*taxonomy\/term\/[0-9]+">' . $term . '<\/a>/', 'Found ' . $term);
}
/**
* Asserts that the term does not exist on a node page.
*/
public function assertNoTaxonomyTerm($term) {
$term = check_plain($term);
$this->assertNoPattern('/<a href="\/.*taxonomy\/term\/[0-9]+">' . $term . '<\/a>/', 'Did not find ' . $term);
}
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* @file
* Contains FeedsMapperUniqueTestCase.
*/
/**
* Class for testing Feeds unique callbacks.
*/
class FeedsMapperUniqueTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Unique target callbacks',
'description' => 'Test unique target callbacks in mappers.',
'group' => 'Feeds',
);
}
/**
* Test mapping target "unique_callbacks".
*/
public function test() {
// Create content type.
$typename = $this->createContentType(array(), array('alpha' => 'text'));
// Create two nodes. Put unique value into field field_alpha.
$node1 = $this->drupalCreateNode(array(
'type' => $typename,
'field_alpha' => array(
LANGUAGE_NONE => array(
0 => array(
'value' => 'Ut wisi',
),
),
),
));
$node2 = $this->drupalCreateNode(array(
'type' => $typename,
'field_alpha' => array(
LANGUAGE_NONE => array(
0 => array(
'value' => 'Lorem',
),
),
),
));
// Create and configure importer.
$this->createImporterConfiguration('Syndication', 'syndication');
$this->setPlugin('syndication', 'FeedsFileFetcher');
$this->setPlugin('syndication', 'FeedsCSVParser');
$this->setSettings('syndication', 'FeedsNodeProcessor', array('bundle' => $typename, 'update_existing' => 2));
$this->addMappings('syndication', array(
0 => array(
'source' => 'title',
'target' => 'title',
),
1 => array(
'source' => 'alpha',
'target' => 'test_unique_target',
'unique' => TRUE,
),
));
// Import CSV file.
$this->importFile('syndication', $this->absolutePath() . '/tests/feeds/content.csv');
$this->assertText('Updated 2 nodes');
// Ensure the updated nodes have the expected title now.
$node1 = node_load($node1->nid, NULL, TRUE);
$this->assertEqual('Ut wisi enim ad minim veniam', $node1->title, 'Node 1 has the expected title.');
$node2 = node_load($node2->nid, NULL, TRUE);
$this->assertEqual('Lorem ipsum', $node2->title, 'Node 2 has the expected title.');
}
}

View File

@@ -0,0 +1,100 @@
<?php
/**
* @file
* Contains FeedsCSVParserTestCase.
*/
/**
* Tests the CSV parser using the UI.
*/
class FeedsCSVParserTestCase extends FeedsWebTestCase {
public static function getInfo() {
return array(
'name' => 'CSV parser functional tests',
'description' => 'Tests the CSV parser using the UI.',
'group' => 'Feeds',
);
}
/**
* Tests parsing a CSV when the mbstring extension is not available.
*/
public function testMbstringExtensionDisabled() {
// Set "feeds_use_mbstring" to FALSE to emulate that the mbstring extension
// is not loaded.
variable_set('feeds_use_mbstring', FALSE);
// Remove items after parsing because in < PHP 5.4 processing items with
// encoding issues leads to test failures because check_plain() can only
// handle UTF-8 encoded strings.
// @see feeds_tests_feeds_after_parse()
variable_set('feeds_tests_feeds_after_parse_empty_items', TRUE);
// Create node type.
$node_type = $this->drupalCreateContentType();
// Create and configure importer.
$this->createImporterConfiguration('Content CSV', 'csv');
$this->setPlugin('csv', 'FeedsFileFetcher');
$this->setPlugin('csv', 'FeedsCSVParser');
$this->setSettings('csv', 'FeedsNodeProcessor', array('bundle' => $node_type->type));
$this->addMappings('csv', array(
0 => array(
'source' => 'id',
'target' => 'guid',
),
1 => array(
'source' => 'text',
'target' => 'title',
),
));
// Ensure that on the CSV parser settings page a message is shown about that
// the mbstring extension is not available.
$this->drupalGet('admin/structure/feeds/csv/settings/FeedsCSVParser');
$this->assertNoField('encoding');
$this->assertText('PHP mbstring extension must be available for character encoding conversion.');
// Try to import a CSV file that is not UTF-8 encoded. No encoding warning
// should be shown, but import should fail.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/encoding_SJIS.csv');
$this->assertNoText('Source file is not in UTF-8 encoding.');
}
/**
* Tests an encoding failure during parsing a CSV.
*/
public function testEncodingFailure() {
// Create node type.
$node_type = $this->drupalCreateContentType();
// Create and configure importer.
$this->createImporterConfiguration('Content CSV', 'csv');
$this->setPlugin('csv', 'FeedsFileFetcher');
$this->setPlugin('csv', 'FeedsCSVParser');
$this->setSettings('csv', 'FeedsNodeProcessor', array('bundle' => $node_type->type));
$this->addMappings('csv', array(
0 => array(
'source' => 'id',
'target' => 'guid',
),
1 => array(
'source' => 'text',
'target' => 'title',
),
));
// Ensure that on the CSV parser settings page a setting for encoding is
// shown.
$this->drupalGet('admin/structure/feeds/csv/settings/FeedsCSVParser');
$this->assertField('encoding');
$this->assertNoText('PHP mbstring extension must be available for character encoding conversion.');
// Try to import a CSV file that is not UTF-8 encoded. Import should be
// halted and an encoding warning should be shown.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/encoding_SJIS.csv');
$this->assertNoText('Failed importing 4 nodes.');
$this->assertText('Source file is not in UTF-8 encoding.');
}
}

View File

@@ -29,17 +29,14 @@ class FeedsSitemapParserTestCase extends FeedsWebTestCase {
0 => array(
'source' => 'changefreq',
'target' => 'title',
'unique' => FALSE,
),
1 => array(
'source' => 'priority',
'target' => 'body',
'unique' => FALSE,
),
2 => array(
'source' => 'lastmod',
'target' => 'created',
'unique' => FALSE,
),
3 => array(
'source' => 'url',
@@ -54,7 +51,6 @@ class FeedsSitemapParserTestCase extends FeedsWebTestCase {
)
);
$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 nodes');
@@ -64,14 +60,14 @@ class FeedsSitemapParserTestCase extends FeedsWebTestCase {
$this->assertEqual($count, 5, 'Accurate number of items in database.');
// Check items against known content of feed.
$items = db_query("SELECT * FROM {feeds_item} WHERE entity_type = 'node' AND feed_nid = :nid ORDER BY nid", array(':nid' => $nid));
$items = db_query("SELECT * FROM {feeds_item} WHERE entity_type = 'node' AND feed_nid = :nid ORDER BY entity_id", array(':nid' => $nid));
// Check first item.
date_default_timezone_set('GMT');
$item = $items->fetchObject();
$node = node_load($item->nid);
$node = node_load($item->entity_id);
$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->body[LANGUAGE_NONE][0]['value'], '0.8', 'Feed item 1 priority is correct.');
$this->assertEqual($node->created, strtotime('2005-01-01'), 'Feed item 1 lastmod is correct.');
$info = feeds_item_info_load('node', $node->nid);
$this->assertEqual($info->url, 'http://www.example.com/', 'Feed item 1 url is correct.');
@@ -79,9 +75,9 @@ class FeedsSitemapParserTestCase extends FeedsWebTestCase {
// Check second item.
$item = $items->fetchObject();
$node = node_load($item->nid);
$node = node_load($item->entity_id);
$this->assertEqual($node->title, 'weekly', 'Feed item 2 changefreq is correct.');
$this->assertEqual($node->body, '', 'Feed item 2 priority is correct.');
$this->assertTrue(empty($node->body[LANGUAGE_NONE]), 'Feed item 2 priority is correct.');
// $node->created is... recently
$info = feeds_item_info_load('node', $node->nid);
$this->assertEqual($info->url, 'http://www.example.com/catalog?item=12&desc=vacation_hawaii', 'Feed item 2 url is correct.');
@@ -89,9 +85,9 @@ class FeedsSitemapParserTestCase extends FeedsWebTestCase {
// Check third item.
$item = $items->fetchObject();
$node = node_load($item->nid);
$node = node_load($item->entity_id);
$this->assertEqual($node->title, 'weekly', 'Feed item 3 changefreq is correct.');
$this->assertEqual($node->body, '', 'Feed item 3 priority is correct.');
$this->assertTrue(empty($node->body[LANGUAGE_NONE]), 'Feed item 3 priority is correct.');
$this->assertEqual($node->created, strtotime('2004-12-23'), 'Feed item 3 lastmod is correct.');
$info = feeds_item_info_load('node', $node->nid);
$this->assertEqual($info->url, 'http://www.example.com/catalog?item=73&desc=vacation_new_zealand', 'Feed item 3 url is correct.');
@@ -99,9 +95,9 @@ class FeedsSitemapParserTestCase extends FeedsWebTestCase {
// Check fourth item.
$item = $items->fetchObject();
$node = node_load($item->nid);
$node = node_load($item->entity_id);
$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->body[LANGUAGE_NONE][0]['value'], '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.');
$info = feeds_item_info_load('node', $node->nid);
$this->assertEqual($info->url, 'http://www.example.com/catalog?item=74&desc=vacation_newfoundland', 'Feed item 4 url is correct.');
@@ -109,9 +105,9 @@ class FeedsSitemapParserTestCase extends FeedsWebTestCase {
// Check fifth item.
$item = $items->fetchObject();
$node = node_load($item->nid);
$node = node_load($item->entity_id);
$this->assertEqual($node->title, '', 'Feed item 5 changefreq is correct.');
$this->assertEqual($node->body, '', 'Feed item 5 priority is correct.');
$this->assertTrue(empty($node->body[LANGUAGE_NONE]), 'Feed item 5 priority is correct.');
$this->assertEqual($node->created, strtotime('2004-11-23'), 'Feed item 5 lastmod is correct.');
$info = feeds_item_info_load('node', $node->nid);
$this->assertEqual($info->url, 'http://www.example.com/catalog?item=83&desc=vacation_usa', 'Feed item 5 url is correct.');

View File

@@ -9,26 +9,28 @@
* Test single feeds.
*/
class FeedsSyndicationParserTestCase extends FeedsWebTestCase {
public static function getInfo() {
return array(
'name' => 'Syndication parsers',
'description' => 'Regression tests for syndication parsers Common syndication and SimplePie. Tests parsers against a set of feeds in the context of Feeds module. <strong>Requires SimplePie parser to be configured correctly.</strong>',
'group' => 'Feeds',
'dependencies' => array('libraries'),
);
}
/**
* Set up test.
*/
public function setUp() {
parent::setUp(array('libraries'));
}
/**
* Run tests.
*/
public function test() {
// Only download simplepie if the plugin doesn't already exist somewhere.
// People running tests locally might have it.
if (!feeds_simplepie_exists()) {
$this->downloadExtractSimplePie('1.3');
$this->assertTrue(feeds_simplepie_exists());
// Reset all the caches!
$this->resetAll();
}
$this->createImporterConfiguration('Syndication', 'syndication');
foreach (array('FeedsSyndicationParser', 'FeedsSimplePieParser') as $parser) {
@@ -38,6 +40,15 @@ class FeedsSyndicationParserTestCase extends FeedsWebTestCase {
$this->assertText('Created ' . $assertions['item_count'] . ' nodes');
}
}
feeds_include_simplepie();
variable_set('feeds_never_use_curl', TRUE);
$link = $GLOBALS['base_url'] . '/testing/feeds/flickr.xml';
$enclosure = new FeedsSimplePieEnclosure(new SimplePie_Enclosure($link));
$enclosure->setAllowedExtensions('xml');
$this->assertEqual(1, $enclosure->getFile('public://')->fid);
}
/**
@@ -54,4 +65,5 @@ class FeedsSyndicationParserTestCase extends FeedsWebTestCase {
),
);
}
}

View File

@@ -12,8 +12,8 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
public static function getInfo() {
return array(
'name' => 'RSS import to nodes',
'description' => '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.',
'name' => 'Processor: Node',
'description' => 'Tests for the node processor.',
'group' => 'Feeds',
);
}
@@ -293,6 +293,49 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
$this->assertText('Created 10 nodes');
$this->assertFeedItemCount(10);
// Enable unpublish missing nodes and import updated feed file.
$this->setSettings('syndication_standalone', 'FeedsNodeProcessor', array('update_non_existent' => FEEDS_UNPUBLISH_NON_EXISTENT, 'update_existing' => FEEDS_REPLACE_EXISTING));
$missing_url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/developmentseed_missing.rss2';
$this->importURL('syndication_standalone', $missing_url);
$this->assertText('Unpublished 1 node');
$this->assertFeedItemCount(10);
// Import again to ensure the message that one node is unpublished doesn't
// reappear (since the node was already unpublished during the previous
// import).
$this->drupalPost('import/syndication_standalone', array(), 'Import');
$this->assertText('There are no new nodes');
$this->assertFeedItemCount(10);
// Re-import the original feed to ensure the unpublished node is updated,
// even though the item is the same since the last time it was available in
// the feed. Fact is that the node was not available in the previous import
// and that should be seen as a change.
$this->importURL('syndication_standalone', $feed_url);
$this->assertText('Updated 1 node');
$this->assertFeedItemCount(10);
// Now delete all items.
$this->drupalPost('import/syndication_standalone/delete-items', array(), 'Delete');
$this->assertText('Deleted 10 nodes');
$this->assertFeedItemCount(0);
// Import again, to reset node counts.
$this->importURL('syndication_standalone', $feed_url);
$this->assertText('Created 10 nodes');
$this->assertFeedItemCount(10);
// Change settings to delete non-existent nodes from feed.
$this->setSettings('syndication_standalone', 'FeedsNodeProcessor', array('update_non_existent' => 'delete'));
$this->importURL('syndication_standalone', $missing_url);
$this->assertText('Removed 1 node');
$this->assertFeedItemCount(9);
// Now delete all items.
$this->drupalPost('import/syndication_standalone/delete-items', array(), 'Delete');
$this->assertText('Deleted 9 nodes');
$this->assertFeedItemCount(0);
// Login with new user with only access content permissions.
$this->drupalLogin($this->auth_user);
@@ -322,7 +365,7 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
/**
* Check that the total number of entries in the feeds_item table is correct.
*/
function assertFeedItemCount($num) {
public function assertFeedItemCount($num) {
$count = db_query("SELECT COUNT(*) FROM {feeds_item} WHERE entity_type = 'node'")->fetchField();
$this->assertEqual($count, $num, 'Accurate number of items in database.');
}
@@ -330,7 +373,7 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
/**
* Check thet contents of the current page for the DS feed.
*/
function assertDevseedFeedContent() {
public function assertDevseedFeedContent() {
$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 &amp; integration with Localize Drupal');
@@ -366,7 +409,7 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
/**
* Test validation of feed URLs.
*/
function testFeedURLValidation() {
public function testFeedURLValidation() {
$edit['feeds[FeedsHTTPFetcher][source]'] = 'invalid://url';
$this->drupalPost('node/add/page', $edit, 'Save');
$this->assertText('The URL invalid://url is invalid.');
@@ -375,7 +418,7 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
/**
* Test using non-normal URLs like feed:// and webcal://.
*/
function testOddFeedSchemes() {
public function testOddFeedSchemes() {
$url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/developmentseed.rss2';
$schemes = array('feed', 'webcal');
@@ -395,7 +438,7 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
/**
* Test that feed elements and links are not found on non-feed nodes.
*/
function testNonFeedNodeUI() {
public function testNonFeedNodeUI() {
// There should not be feed links on an article node.
$non_feed_node = $this->drupalCreateNode(array('type' => 'article'));
$this->drupalGet('node/' . $non_feed_node->nid);
@@ -408,13 +451,12 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
}
/**
* Test that nodes will not be created if the user is unauthorized to create
* Test that nodes will not be created if the user is unauthorized to create
* them.
*/
public function testAuthorize() {
// Create a user with limited permissions. We can't use
// $this->drupalCreateUser here because we need to to set a specific user
// Create a user with limited permissions. We can't use
// $this->drupalCreateUser here because we need to to set a specific user
// name.
$edit = array(
'name' => 'Development Seed',
@@ -423,7 +465,7 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
'status' => 1,
);
$account = user_save(drupal_anonymous_user(), $edit);
$account = user_save(drupal_anonymous_user(), $edit);
// Adding a mapping to the user_name will invoke authorization.
$this->addMappings('syndication',
@@ -438,7 +480,7 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
$nid = $this->createFeedNode();
$this->assertText('Failed importing 10 nodes.');
$this->assertText('User ' . $account->name . ' is not authorized to create content type article.');
$this->assertText('The user ' . $account->name . ' is not authorized to create content of type article.');
$node_count = db_query("SELECT COUNT(*) FROM {node}")->fetchField();
// We should have 1 node, the feed node.
@@ -455,4 +497,268 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
$node_count = db_query("SELECT COUNT(*) FROM {node}")->fetchField();
$this->assertEqual($node_count, 11, t('Correct number of nodes in the database.'));
}
/**
* Tests expiring nodes.
*/
public function testExpiry() {
// Create importer configuration.
$this->setSettings('syndication', NULL, array('content_type' => ''));
$this->setSettings('syndication', 'FeedsNodeProcessor', array(
'expire' => 2592000,
));
// Create importer.
$this->importURL('syndication');
// Set date of a few nodes to current date so they don't expire.
$edit = array(
'date' => date('Y-m-d'),
);
$this->drupalPost('node/2/edit', $edit, 'Save');
$this->assertText(date('m/d/Y'), 'Found correct date.');
$this->drupalPost('node/5/edit', $edit, 'Save');
$this->assertText(date('m/d/Y'), 'Found correct date.');
// Run cron to schedule jobs.
$this->cronRun();
// Set feeds source expire to run immediately.
db_update('job_schedule')
->fields(array(
'next' => 0,
))
->condition('name', 'feeds_source_expire')
->execute();
// Run cron to execute scheduled jobs.
$this->cronRun();
// Query the feeds_items table and count the number of entries.
$row_count = db_query('SELECT COUNT(*) FROM {feeds_item}')->fetchField();
// Check that number of feeds items is equal to the expected items.
$this->assertEqual($row_count, 2, 'Nodes expired.');
}
/**
* Tests process in background option.
*/
public function testImportInBackground() {
// Just remove the mappings rather than creating a new importer.
$this->removeMappings('syndication', $this->getCurrentMappings('syndication'));
// Set our process limit to something simple.
variable_set('feeds_process_limit', 5);
$this->setPlugin('syndication', 'FeedsFileFetcher');
$this->setPlugin('syndication', 'FeedsCSVParser');
$this->setSettings('syndication', NULL, array(
'content_type' => '',
'process_in_background' => TRUE,
'import_period' => FEEDS_SCHEDULE_NEVER,
));
$this->addMappings('syndication', array(
0 => array(
'source' => 'title',
'target' => 'title',
),
1 => array(
'source' => 'GUID',
'target' => 'guid',
'unique' => TRUE,
),
));
$this->importFile('syndication', $this->absolutePath() . '/tests/feeds/many_nodes_ordered.csv');
$this->assertEqual(5, db_query("SELECT COUNT(*) FROM {node}")->fetchField());
// The feed should still be scheduled because it is being processed.
// @see https://drupal.org/node/2275893
$this->cronRun();
$this->assertEqual(86, db_query("SELECT COUNT(*) FROM {node}")->fetchField());
}
/**
* Tests skip new items.
*/
public function testSkipNewItems() {
// Include FeedsProcessor.inc so processor related constants are available.
module_load_include('inc', 'feeds', 'plugins/FeedsProcessor');
// Attach to standalone importer.
$this->setSettings('syndication', NULL, array('content_type' => ''));
// Set that new items should not be imported.
$this->setSettings('syndication', 'FeedsNodeProcessor', array(
'insert_new' => FEEDS_SKIP_NEW,
'update_existing' => FEEDS_SKIP_EXISTING,
));
// Make title unique target.
$this->removeMappings('syndication', $this->getCurrentMappings('syndication'));
$this->addMappings('syndication', array(
0 => array(
'source' => 'title',
'target' => 'title',
'unique' => TRUE,
),
1 => array(
'source' => 'description',
'target' => 'body',
),
2 => array(
'source' => 'timestamp',
'target' => 'created',
),
));
// Do a first import, no nodes should be created.
$edit = array(
'feeds[FeedsHTTPFetcher][source]' => $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/developmentseed.rss2',
);
$this->drupalPost('import/syndication', $edit, 'Import');
$this->assertText('There are no new nodes');
// Now create two nodes with titles that are present in the source
// "developmentseed.rss2".
$this->drupalCreateNode(array(
'type' => 'article',
'title' => 'Open Atrium Translation Workflow: Two Way Translation Updates',
));
$this->drupalCreateNode(array(
'type' => 'article',
'title' => 'Week in DC Tech: October 5th Edition',
));
// Import again. Since the processor is set to not update as well, nothing
// should be imported.
$this->drupalPost('import/syndication', array(), 'Import');
$this->assertText('There are no new nodes');
// Now set importer to update existing.
$this->setSettings('syndication', 'FeedsNodeProcessor', array(
'update_existing' => FEEDS_UPDATE_EXISTING,
));
// And import again. Two nodes should be updated.
$this->drupalPost('import/syndication', array(), 'Import');
$this->assertText('Updated 2 nodes.');
// Change "insert_new" setting to insert new items to verify if changing the
// setting later has the effect that new items will be imported as yet.
$this->setSettings('syndication', 'FeedsNodeProcessor', array(
'insert_new' => FEEDS_INSERT_NEW,
));
// Import. Eight nodes should be created. No nodes should be updated.
$this->drupalPost('import/syndication', array(), 'Import');
$this->assertText('Created 8 nodes.');
$this->assertNoText('Updated 2 nodes.');
}
/**
* Tests if the target "changed" works as expected.
*/
public function testChangedTarget() {
// Create and configure importer.
$this->createImporterConfiguration('Content CSV', 'csv');
$this->setSettings('csv', NULL, array('content_type' => '', 'import_period' => FEEDS_SCHEDULE_NEVER));
$this->setPlugin('csv', 'FeedsFileFetcher');
$this->setPlugin('csv', 'FeedsCSVParser');
$this->addMappings('csv', array(
0 => array(
'source' => 'title',
'target' => 'title',
),
// Borrow the timestamp value from the "created" column in the csv.
1 => array(
'source' => 'created',
'target' => 'changed',
),
));
// Import CSV file.
$this->importFile('csv', $this->absolutePath() . '/tests/feeds/content.csv');
$this->assertText('Created 2 nodes');
// Assert changed date of nodes.
$expected_values = array(
1 => array(
'changed' => 1251936720,
),
2 => array(
'changed' => 1251932360,
),
);
for ($i = 1; $i <= 2; $i++) {
$node = node_load($i);
$this->assertEqual($expected_values[$i]['changed'], $node->changed);
}
}
/**
* Tests the FeedsSource::pushImport() method.
*/
public function testPushImport() {
// Attach to standalone importer.
$this->setSettings('syndication', NULL, array('content_type' => ''));
$raw = file_get_contents(dirname(__FILE__) . '/feeds/developmentseed.rss2');
feeds_source('syndication', 0)->pushImport(new FeedsFetcherResult($raw));
$this->assertEqual(10, db_query("SELECT COUNT(*) FROM {node}")->fetchField());
}
/**
* Tests the FeedsSource::pushImport() method with a CSV file.
*/
public function testPushImportWithCSV() {
// Attach to standalone importer and configure.
$this->setSettings('syndication', NULL, array('content_type' => ''));
$this->setPlugin('syndication', 'FeedsCSVParser');
$this->removeMappings('syndication', $this->getCurrentMappings('syndication'));
$this->addMappings('syndication', array(
0 => array(
'source' => 'title',
'target' => 'title',
),
));
$raw = file_get_contents($this->absolutePath() . '/tests/feeds/many_nodes.csv');
feeds_source('syndication', 0)->pushImport(new FeedsFetcherResult($raw));
$this->assertEqual(86, db_query("SELECT COUNT(*) FROM {node}")->fetchField());
}
/**
* Tests if target item is not updated when only non-mapped data on the source changed.
*/
public function testIrrelevantUpdate() {
// Include FeedsProcessor.inc so processor related constants are available.
module_load_include('inc', 'feeds', 'plugins/FeedsProcessor');
// Attach to standalone importer and configure.
$this->setSettings('syndication', NULL, array('content_type' => ''));
$this->setPlugin('syndication', 'FeedsFileFetcher');
$this->setPlugin('syndication', 'FeedsCSVParser');
$this->removeMappings('syndication', $this->getCurrentMappings('syndication'));
$this->addMappings('syndication', array(
0 => array(
'source' => 'name',
'target' => 'title',
'unique' => TRUE,
),
));
// Import file.
$this->importFile('syndication', $this->absolutePath() . '/tests/feeds/users.csv');
$this->assertText('Created 5 nodes');
// Ensure that no nodes are updated when only non-mapped columns changed.
$this->setSettings('syndication', 'FeedsNodeProcessor', array(
'skip_hash_check' => FALSE,
'update_existing' => FEEDS_UPDATE_EXISTING,
));
$this->importFile('syndication', $this->absolutePath() . '/tests/feeds/users_updated.csv');
$this->assertText('There are no new nodes.');
}
}

View File

@@ -11,16 +11,17 @@
class FeedsCSVtoTermsTest extends FeedsWebTestCase {
public static function getInfo() {
return array(
'name' => 'CSV import to taxonomy',
'name' => 'Processor: Taxonomy',
'description' => 'Tests a standalone import configuration that uses file fetcher and CSV parser to import taxonomy terms from a CSV file.',
'group' => 'Feeds',
);
}
/**
* Test node creation, refreshing/deleting feeds and feed items.
* Set up test.
*/
public function test() {
public function setUp() {
parent::setUp();
// Create an importer.
$this->createImporterConfiguration('Term import', 'term_import');
@@ -29,6 +30,25 @@ class FeedsCSVtoTermsTest extends FeedsWebTestCase {
$this->setPlugin('term_import', 'FeedsFileFetcher');
$this->setPlugin('term_import', 'FeedsCSVParser');
$this->setPlugin('term_import', 'FeedsTermProcessor');
// Create vocabulary.
$edit = array(
'name' => 'Addams vocabulary',
'machine_name' => 'addams',
);
$this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
$this->setSettings('term_import', 'FeedsTermProcessor', array('bundle' => 'addams'));
// Use standalone form.
$this->setSettings('term_import', NULL, array('content_type' => ''));
}
/**
* Test term creation, refreshing/deleting feeds and feed items.
*/
public function test() {
$mappings = array(
0 => array(
'source' => 'name',
@@ -38,23 +58,6 @@ class FeedsCSVtoTermsTest extends FeedsWebTestCase {
);
$this->addMappings('term_import', $mappings);
// Use standalone form.
$edit = array(
'content_type' => '',
);
$this->drupalPost('admin/structure/feeds/term_import/settings', $edit, 'Save');
$edit = array(
'name' => 'Addams vocabulary',
'machine_name' => 'addams',
);
$this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
$edit = array(
'vocabulary' => 'addams',
);
$this->drupalPost('admin/structure/feeds/term_import/settings/FeedsTermProcessor', $edit, t('Save'));
// Import and assert.
$this->importFile('term_import', $this->absolutePath() . '/tests/feeds/users.csv');
$this->assertText('Created 5 terms');
@@ -89,4 +92,288 @@ class FeedsCSVtoTermsTest extends FeedsWebTestCase {
$this->assertNoText('Gomez');
$this->assertNoText('Pugsley');
}
/**
* Test that saving an invalid vocabulary throws an exception.
*/
public function testInvalidVocabulary() {
$mappings = array(
0 => array(
'source' => 'name',
'target' => 'name',
'unique' => 1,
),
);
$this->addMappings('term_import', $mappings);
// Force configuration to be invalid.
$config = unserialize(db_query("SELECT config FROM {feeds_importer} WHERE id = :id", array(':id' => 'term_import'))->fetchField());
$config['processor']['config']['bundle'] = 'does_not_exist';
db_update('feeds_importer')
->fields(array('config' => serialize($config)))
->condition('id', 'term_import')
->execute();
// Import and assert.
$this->importFile('term_import', $this->absolutePath() . '/tests/feeds/users.csv');
$this->assertText(t('No vocabulary defined for Taxonomy Term processor.'));
}
/**
* Tests that terms mapped to their parent by GUID are from the same vocabulary.
*/
public function testParentTargetByGUID() {
// Create an other vocabulary.
$vocabulary1 = 'addams';
$vocabulary2 = strtolower($this->randomName());
$edit = array(
'name' => $this->randomString(),
'machine_name' => $vocabulary2,
);
$this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
// Add mappings for the first importer.
$this->addMappings('term_import',
array(
0 => array(
'source' => 'guid',
'target' => 'guid',
'unique' => TRUE,
),
1 => array(
'source' => 'name',
'target' => 'name',
),
2 => array(
'source' => 'parentguid',
'target' => 'parentguid',
),
)
);
// Create a second importer.
$this->createImporterConfiguration('Term import 2', 'term_import2');
$this->setSettings('term_import2', NULL, array('content_type' => ''));
// Set and configure plugins and mappings.
$this->setPlugin('term_import2', 'FeedsFileFetcher');
$this->setPlugin('term_import2', 'FeedsCSVParser');
$this->setPlugin('term_import2', 'FeedsTermProcessor');
$this->setSettings('term_import2', 'FeedsTermProcessor', array('bundle' => $vocabulary2));
// Add mappings for the second importer.
$this->addMappings('term_import2',
array(
0 => array(
'source' => 'guid',
'target' => 'guid',
'unique' => TRUE,
),
1 => array(
'source' => 'name',
'target' => 'name',
),
2 => array(
'source' => 'parentguid',
'target' => 'parentguid',
),
)
);
$values = array(
1 => 'Europe',
2 => 'Belgium',
);
// Import file using the first importer.
$this->importFile('term_import', $this->absolutePath() . '/tests/feeds/terms.csv');
$this->assertText('Created 2 terms.');
// Assert that two terms were created in the first vocabulary.
$terms = entity_load('taxonomy_term', array_keys($values));
foreach ($terms as $tid => $term) {
$this->assertEqual($values[$tid], $term->name);
$this->assertEqual($vocabulary1, $term->vocabulary_machine_name);
}
// Assert that the second term's parent is the first term.
$parents = taxonomy_get_parents($terms[2]->tid);
$message = format_string('The term @term is correctly linked to its parent.', array('@term' => $terms[2]->name));
if (!empty($parents)) {
$parent = current($parents);
$this->assertEqual(1, $parent->tid, $message);
}
else {
$this->fail($message);
}
$values = array(
3 => 'Europe',
4 => 'Belgium',
);
// Now import the file using the second importer.
$this->importFile('term_import2', $this->absolutePath() . '/tests/feeds/terms.csv');
$this->assertText('Created 2 terms.');
// Assert that two terms were created in the second vocabulary.
$terms = entity_load('taxonomy_term', array_keys($values));
foreach ($terms as $tid => $term) {
$this->assertEqual($values[$tid], $term->name);
$this->assertEqual($vocabulary2, $term->vocabulary_machine_name);
}
// Assert that the second term's parent is the first term.
$parents = taxonomy_get_parents($terms[4]->tid);
$message = format_string('The term @term is correctly linked to its parent.', array('@term' => $terms[4]->name));
if (!empty($parents)) {
$parent = current($parents);
$this->assertEqual(3, $parent->tid, $message);
}
else {
$this->fail($message);
}
}
/**
* Tests that terms mapped to their parent by GUID are from the same vocabulary.
*/
public function testParentTargetByName() {
// Create an other vocabulary.
$vocabulary1 = 'addams';
$vocabulary2 = strtolower($this->randomName());
$edit = array(
'name' => $this->randomString(),
'machine_name' => $vocabulary2,
);
$this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
// Add mappings for the first importer.
$this->addMappings('term_import',
array(
0 => array(
'source' => 'guid',
'target' => 'guid',
'unique' => TRUE,
),
1 => array(
'source' => 'name',
'target' => 'name',
),
2 => array(
'source' => 'parent',
'target' => 'parent',
),
)
);
// Create a second importer.
$this->createImporterConfiguration('Term import 2', 'term_import2');
$this->setSettings('term_import2', NULL, array('content_type' => ''));
// Set and configure plugins and mappings.
$this->setPlugin('term_import2', 'FeedsFileFetcher');
$this->setPlugin('term_import2', 'FeedsCSVParser');
$this->setPlugin('term_import2', 'FeedsTermProcessor');
$this->setSettings('term_import2', 'FeedsTermProcessor', array('bundle' => $vocabulary2));
// Add mappings for the second importer.
$this->addMappings('term_import2',
array(
0 => array(
'source' => 'guid',
'target' => 'guid',
'unique' => TRUE,
),
1 => array(
'source' => 'name',
'target' => 'name',
),
2 => array(
'source' => 'parent',
'target' => 'parent',
),
)
);
$values = array(
1 => 'Europe',
2 => 'Belgium',
);
// Import file using the first importer.
$this->importFile('term_import', $this->absolutePath() . '/tests/feeds/terms.csv');
$this->assertText('Created 2 terms.');
// Assert that two terms were created in the first vocabulary.
$terms = entity_load('taxonomy_term', array_keys($values));
foreach ($terms as $tid => $term) {
$this->assertEqual($values[$tid], $term->name);
$this->assertEqual($vocabulary1, $term->vocabulary_machine_name);
}
// Assert that the second term's parent is the first term.
$parents = taxonomy_get_parents($terms[2]->tid);
$message = format_string('The term @term is correctly linked to its parent.', array('@term' => $terms[2]->name));
if (!empty($parents)) {
$parent = current($parents);
$this->assertEqual(1, $parent->tid, $message);
}
else {
$this->fail($message);
}
$values = array(
3 => 'Europe',
4 => 'Belgium',
);
// Now import the file using the second importer.
$this->importFile('term_import2', $this->absolutePath() . '/tests/feeds/terms.csv');
$this->assertText('Created 2 terms.');
// Assert that two terms were created in the second vocabulary.
$terms = entity_load('taxonomy_term', array_keys($values));
foreach ($terms as $tid => $term) {
$this->assertEqual($values[$tid], $term->name);
$this->assertEqual($vocabulary2, $term->vocabulary_machine_name);
}
// Assert that the second term's parent is the first term.
$parents = taxonomy_get_parents($terms[4]->tid);
$message = format_string('The term @term is correctly linked to its parent.', array('@term' => $terms[4]->name));
if (!empty($parents)) {
$parent = current($parents);
$this->assertEqual(3, $parent->tid, $message);
}
else {
$this->fail($message);
}
}
/**
* Test replacing terms on subsequent imports.
*/
public function testReplaceTerms() {
$mappings = array(
0 => array(
'source' => 'name',
'target' => 'name',
'unique' => 1,
),
);
$this->addMappings('term_import', $mappings);
// Configure the processor to "Replace existing terms".
$this->setSettings('term_import', 'FeedsTermProcessor', array(
'skip_hash_check' => TRUE,
'update_existing' => 1,
));
// Import first time.
$this->importFile('term_import', $this->absolutePath() . '/tests/feeds/users.csv');
$this->assertText('Created 5 terms');
// Import again to replace terms.
$this->importFile('term_import', $this->absolutePath() . '/tests/feeds/users.csv');
$this->assertText('Updated 5 terms.');
}
}

View File

@@ -118,5 +118,20 @@ class FeedsCSVtoUsersTest extends FeedsWebTestCase {
$this->assertTrue($account, 'Imported user account loaded.');
$account->pass_raw = 'fest';
$this->drupalLogin($account);
// Login as admin.
$this->drupalLogin($this->admin_user);
// Import modified CSV file, one (valid) user is missing.
$this->setSettings('user_import', 'FeedsUserProcessor', array('update_existing' => 2, 'update_non_existent' => 'block'));
$this->importFile('user_import', $this->absolutePath() . '/tests/feeds/users2.csv');
$this->assertText('Blocked 1 user');
$this->assertText('Failed importing 2 user');
// Import the original CSV file again.
$this->importFile('user_import', $this->absolutePath() . '/tests/feeds/users.csv');
$this->assertText('Updated 1 user');
$this->assertText('Failed importing 2 user');
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* @file
* Contains FeedsPushTest.
*/
/**
* Tests for PubSubHubbub support in feeds.
*/
class FeedsPushTest extends FeedsWebTestCase {
public static function getInfo() {
return array(
'name' => 'PubSubHubbub',
'description' => 'Tests for PubSubHubbub support.',
'group' => 'Feeds',
);
}
/**
* Tests that PubSubHubbub challenge is escaped.
*/
public function test() {
$this->createImporterConfiguration('Push', 'push');
$subscription = new PuSHSubscription('push', 0, 'http://example.com', 'http://example.com/feed', 'secret', 'unsubscribe', array());
$subscription->save();
$challenge = '<script>alert();</script>';
$options = array(
'query' => array(
'hub.mode' => 'unsubscribe',
'hub.challenge' => $challenge,
'hub.topic' => 'http://example.com/feed',
),
);
$this->drupalGet("feeds/importer/push/0", $options);
$this->assertResponse(200);
$this->assertRaw(check_plain($challenge), 'Challenge was escaped.');
$this->assertNoRaw($challenge, 'Raw challenge not found.');
}
}

View File

@@ -151,14 +151,14 @@ class FeedsSchedulerTestCase extends FeedsWebTestCase {
// Set expire settings, check rescheduling.
$max_last = db_query("SELECT MAX(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 0")->fetchField();
$min_last = db_query("SELECT MIN(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 0")->fetchField();
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND last <> 0 AND scheduled = 0")->fetchField());
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_expire'")->fetchField());
$this->drupalLogin($this->admin_user);
$this->setSettings('syndication', 'FeedsNodeProcessor', array('expire' => 86400));
$this->drupalLogout();
sleep(1);
$this->cronRun();
// There should be a feeds_importer_expire job now, and all last fields should be reset.
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND last <> 0 AND scheduled = 0 AND period = 3600")->fetchField());
// There should be 20 feeds_source_expire jobs now, and all last fields should be reset.
$this->assertEqual(count($nids), db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_expire' AND last <> 0 AND scheduled = 0 AND period = 3600")->fetchField());
$new_max_last = db_query("SELECT MAX(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 0")->fetchField();
$new_min_last = db_query("SELECT MIN(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 0")->fetchField();
$this->assertNotEqual($new_max_last, $max_last);
@@ -179,18 +179,19 @@ class FeedsSchedulerTestCase extends FeedsWebTestCase {
$this->assertNotEqual($new_min_last, $min_last);
$this->assertEqual($new_max_last, $new_min_last);
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period <> 3600")->fetchField());
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND period = 3600 AND last = :last", array(':last' => $new_min_last))->fetchField());
$this->assertEqual(count($nids), db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_expire' AND period = 3600 AND last = :last", array(':last' => $new_min_last))->fetchField());
// Delete source, delete importer, check schedule.
$this->drupalLogin($this->admin_user);
$nid = array_shift($nids);
$this->drupalPost("node/$nid/delete", array(), t('Delete'));
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND id = :nid", array(':nid' => $nid))->fetchField());
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_expire' AND id = :nid", array(':nid' => $nid))->fetchField());
$this->assertEqual(count($nids), db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import'")->fetchField());
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND id = 0")->fetchField());
$this->assertEqual(count($nids), db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_expire'")->fetchField());
$this->drupalPost('admin/structure/feeds/syndication/delete', array(), t('Delete'));
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND id = 0")->fetchField());
$this->assertEqual(count($nids), db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_expire'")->fetchField());
$this->assertEqual(count($nids), db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import'")->fetchField());
}
@@ -226,23 +227,17 @@ class FeedsSchedulerTestCase extends FeedsWebTestCase {
db_query("UPDATE {job_schedule} SET next = 0");
$this->drupalPost('import/node/delete-items', array(), 'Delete');
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField());
$node_count = db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField();
$this->assertEqual(0, $node_count);
// Hit cron (item count / limit) times, assert correct number of articles.
for ($i = 0; $i < ceil(86 / $limit); $i++) {
// Hit cron for importing, until we have all items.
while ($node_count < 86) {
$this->cronRun();
sleep(1);
if ($limit * ($i + 1) < 86) {
$count = $limit * ($i + 1);
$period = 0; // Import should be rescheduled for ASAP.
}
else {
$count = 86; // We've reached our total of 86.
$period = 1800; // Hence we should find the Source's default period.
}
$this->assertEqual($count, db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField());
$this->assertEqual($period, db_query("SELECT period FROM {job_schedule} WHERE type = 'node' AND id = 0")->fetchField());
$node_count = db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField();
}
$this->assertEqual(86, db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField(), 'Number of nodes is correct after batched importing via cron.');
// Import should be rescheduled for 1800 seconds.
$this->assertEqual(1800, db_query("SELECT period FROM {job_schedule} WHERE type = 'node' AND id = 0")->fetchField());
}
// Delete a couple of nodes, then hit cron again. They should not be replaced

View File

@@ -3,12 +3,11 @@ description = "Support module for Feeds related testing."
package = Testing
version = VERSION
core = 7.x
files[] = feeds_test.module
hidden = TRUE
; Information added by drupal.org packaging script on 2012-10-24
version = "7.x-2.0-alpha7"
; Information added by Drupal.org packaging script on 2016-02-21
version = "7.x-2.0-beta2"
core = "7.x"
project = "feeds"
datestamp = "1351111319"
datestamp = "1456055647"

View File

@@ -19,6 +19,21 @@ function feeds_tests_menu() {
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$items['testing/feeds/files-remote.csv'] = array(
'page callback' => 'feeds_tests_files_remote',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$items['testing/feeds/files-empty-alt-title.csv'] = array(
'page callback' => 'feeds_tests_files_empty_alt_title',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$items['testing/feeds/files-empty.csv'] = array(
'page callback' => 'feeds_tests_files_empty',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
@@ -37,6 +52,11 @@ function feeds_tests_theme() {
'path' => drupal_get_path('module', 'feeds_tests') . '/feeds',
'template' => 'feeds-tests-files',
),
'feeds_tests_files_empty' => array(
'variables' => array('files' => array()),
'path' => drupal_get_path('module', 'feeds_tests') . '/feeds',
'template' => 'feeds-tests-files-empty',
),
);
}
@@ -53,7 +73,7 @@ function feeds_tests_flickr() {
);
$path = drupal_get_path('module', 'feeds_tests') . '/feeds/assets';
foreach ($images as &$image) {
$image = url("$path/$image", array('absolute' => TRUE));
$image = file_create_url("$path/$image");
}
drupal_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8');
print theme('feeds_tests_flickr', array('image_urls' => $images));
@@ -78,16 +98,119 @@ function feeds_tests_files() {
}
/**
* Implements hook_feeds_processor_targets_alter()
* Outputs a CSV file pointing to files to download.
*/
function feeds_tests_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
$targets['test_target'] = array(
'name' => t('Test Target'),
'description' => t('This is a test target.'),
function feeds_tests_files_remote() {
$images = array(
0 => 'tubing.jpeg',
1 => 'foosball.jpeg',
2 => 'attersee.jpeg',
3 => 'hstreet.jpeg',
4 => 'la fayette.jpeg',
);
$path = drupal_get_path('module', 'feeds_tests') . '/feeds/assets';
foreach ($images as &$image) {
$image = file_create_url("$path/$image");
}
drupal_add_http_header('Content-Type', 'text/plain; charset=utf-8');
print theme('feeds_tests_files', array('files' => $images));
}
/**
* Outputs a CSV file pointing to files without alt/title.
*
* This is used to test if alt/title attributes are removed on a second import.
*/
function feeds_tests_files_empty_alt_title() {
$images = array(
0 => 'tubing.jpeg',
1 => 'foosball.jpeg',
2 => 'attersee.jpeg',
3 => 'hstreet.jpeg',
4 => 'la fayette.jpeg',
);
$path = drupal_get_path('module', 'feeds_tests') . '/feeds/assets';
foreach ($images as &$image) {
$image = file_create_url("$path/$image");
}
drupal_add_http_header('Content-Type', 'text/plain; charset=utf-8');
print theme('feeds_tests_files_empty', array('files' => $images));
}
/**
* Outputs a CSV file pointing to no files.
*
* This is used to test if files are removed on a second import.
*/
function feeds_tests_files_empty() {
$images = array(
0 => '',
1 => '',
2 => '',
3 => '',
4 => '',
);
drupal_add_http_header('Content-Type', 'text/plain; charset=utf-8');
print theme('feeds_tests_files_empty', array('files' => $images));
}
/**
* Implements hook_feeds_processor_targets().
*/
function feeds_tests_feeds_processor_targets($entity_type, $bundle) {
$targets = array();
// Tests that old keys still work.
$targets['test_target_compat'] = array(
'name' => t('Old style target'),
'callback' => 'feeds_tests_mapper_set_target',
'summary_callback' => 'feeds_tests_mapper_summary',
'form_callback' => 'feeds_tests_mapper_form',
);
$targets['test_target'] = array(
'name' => t('Test Target'),
'description' => t('This is a test target.'),
'callback' => 'feeds_tests_mapper_set_target',
'summary_callbacks' => array('feeds_tests_mapper_summary', 'feeds_tests_mapper_summary_2'),
'form_callbacks' => array('feeds_tests_mapper_form', 'feeds_tests_mapper_form_2'),
'preprocess_callbacks' => array(array(new FeedsTestsPreprocess(), 'callback')),
);
$targets['test_unique_target'] = array(
'name' => t('Test unique target'),
'description' => t('This is a unique test target.'),
'callback' => 'feeds_tests_mapper_set_target',
'optional_unique' => TRUE,
'unique_callbacks' => array('feeds_tests_mapper_unique'),
'preprocess_callbacks' => array(
array('FeedsTestsPreprocess', 'callback'),
// Make sure that invalid callbacks are filtered.
'__feeds_tests_invalid_callback',
),
);
return $targets;
}
/**
* Implements hook_feeds_processor_targets_alter().
*/
function feeds_tests_feeds_processor_targets_alter(array &$targets, $entity_type, $bundle) {
if (!isset($targets['test_target'])) {
return;
}
$targets['test_target']['description'] = t('The target description was altered.');
}
/**
* Preprocess callback for test_target.
*
* @see feeds_tests_feeds_processor_targets()
*/
function feeds_tests_preprocess_callback(array $target, array &$mapping) {
$mapping['required_value'] = TRUE;
}
/**
@@ -95,8 +218,12 @@ function feeds_tests_feeds_processor_targets_alter(&$targets, $entity_type, $bun
*
* @see my_module_set_target()
*/
function feeds_tests_mapper_set_target($source, $entity, $target, $value, $mapping) {
$entity->body['und'][0]['value'] = serialize($mapping);
function feeds_tests_mapper_set_target(FeedsSource $source, $entity, $target, array $values, array $mapping) {
if (empty($mapping['required_value'])) {
trigger_error('The required value was not set.', E_USER_ERROR);
}
$entity->body['und'][0]['value'] = serialize($mapping);
}
/**
@@ -104,12 +231,12 @@ function feeds_tests_mapper_set_target($source, $entity, $target, $value, $mappi
*
* @see my_module_summary_callback()
*/
function feeds_tests_mapper_summary($mapping, $target, $form, $form_state) {
function feeds_tests_mapper_summary(array $mapping, $target, array $form, array $form_state) {
$options = array(
'option1' => t('Option 1'),
'option1' => t('Option 1'),
'option2' => t('Another Option'),
'option3' => t('Option for select'),
'option4' => t('Another One')
'option3' => t('Option for select'),
'option4' => t('Another One'),
);
$items = array();
@@ -139,10 +266,20 @@ function feeds_tests_mapper_summary($mapping, $target, $form, $form_state) {
return drupal_render($list);
}
/*
/**
* Provides a second summary callback.
*
* @see my_module_summary_callback()
*/
function feeds_tests_mapper_summary_2(array $mapping, $target, array $form, array $form_state) {
$mapping += array('second_value' => '');
return t('Second summary: @value', array('@value' => $mapping['second_value']));
}
/**
* Provides the form with mapper settings.
*/
function feeds_tests_mapper_form($mapping, $target, $form, $form_state) {
function feeds_tests_mapper_form(array $mapping, $target, array $form, array $form_state) {
$mapping += array(
'checkbox' => FALSE,
'textfield' => '',
@@ -182,3 +319,67 @@ function feeds_tests_mapper_form($mapping, $target, $form, $form_state) {
);
}
/**
* Provides a second settings form.
*/
function feeds_tests_mapper_form_2(array $mapping, $target, array $form, array $form_state) {
return array(
'second_value' => array(
'#type' => 'textfield',
'#title' => t('The second callback value'),
'#default_value' => !empty($mapping['second_value']) ? $mapping['second_value'] : '',
),
);
}
/**
* Callback for unique_callbacks for test_target mapper.
*
* @see feeds_tests_feeds_processor_targets()
*/
function feeds_tests_mapper_unique(FeedsSource $source, $entity_type, $bundle, $target, array $values) {
$query = new EntityFieldQuery();
$result = $query
->entityCondition('entity_type', $entity_type)
->entityCondition('bundle', $bundle)
->fieldCondition('field_alpha', 'value', $values)
->execute();
if (!empty($result[$entity_type])) {
return key($result[$entity_type]);
}
}
/**
* Implements hook_feeds_after_parse().
*
* Empties the list of items to import in case the test says that there are
* items in there with encoding issues. These items can not be processed during
* tests without having a test failure because in < PHP 5.4 that would produce
* the following warning:
* htmlspecialchars(): Invalid multibyte sequence in argument
*
* @see FeedsCSVParserTestCase::testMbstringExtensionDisabled()
*/
function feeds_tests_feeds_after_parse(FeedsSource $source, FeedsParserResult $result) {
if (variable_get('feeds_tests_feeds_after_parse_empty_items', FALSE)) {
// Remove all items. No items will be processed.
$result->items = array();
}
}
/**
* Helper class to ensure callbacks can be objects.
*/
class FeedsTestsPreprocess {
/**
* Preprocess callback for test_target.
*
* @see feeds_tests_feeds_processor_targets()
*/
public static function callback(array $target, array &$mapping) {
$mapping['required_value'] = TRUE;
}
}

View File

@@ -0,0 +1,359 @@
<?php
/**
* @file
* Tests for http_request.inc.
*/
/**
* Tests for the http library.
*/
class FeedsHTTPRequestTestCase extends FeedsUnitTestHelper {
public static function getInfo() {
return array(
'name' => 'HTTP library',
'description' => 'Tests for Feeds HTTP library.',
'group' => 'Feeds',
);
}
public function setUp() {
parent::setUp();
feeds_include_library('http_request.inc', 'http_request');
}
/**
* Tests http_request_find_feeds().
*/
public function testHTTPRequestFindFeeds() {
$html = <<<EOF
<html>
<head>
<title>Welcome to Example.com</title>
<link rel="stylesheet" type="text/css" media="screen, projection" href="/stuff.css" >
<link rel="search" title="Something" href="//example.com/search">
<link rel="alternate" title="Something RSS" href="http://example.com/rss.xml" type="application/rss+xml">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
</head>
<body>
This is a body.
</body>
</html
EOF;
$links = http_request_find_feeds($html);
$this->assertEqual(count($links), 1);
$this->assertEqual($links[0], 'http://example.com/rss.xml');
// Test single quoted HTML.
$links = http_request_find_feeds(str_replace('"', "'", $html));
$this->assertEqual(count($links), 1);
$this->assertEqual($links[0], 'http://example.com/rss.xml');
}
/**
* Tests http_request_create_absolute_url().
*/
public function testHTTPRequestCreateAbsoluteUrl() {
$test_urls = array(
// Rels that do not start with "/".
array(
'rel' => 'h',
'base' => 'http://www',
'expected' => 'http://www/h',
),
array(
'rel' => 'h',
'base' => 'http://www/',
'expected' => 'http://www/h',
),
array(
'rel' => 'h',
'base' => 'http://www/?c;d=e#f',
'expected' => 'http://www/h',
),
array(
'rel' => 'h',
'base' => 'http://www/a/b',
'expected' => 'http://www/a/h',
),
array(
'rel' => 'h/j',
'base' => 'http://www',
'expected' => 'http://www/h/j',
),
array(
'rel' => 'h/j',
'base' => 'http://www/',
'expected' => 'http://www/h/j',
),
array(
'rel' => 'h/j',
'base' => 'http://www/?c;d=e#f',
'expected' => 'http://www/h/j',
),
array(
'rel' => 'h/j',
'base' => 'http://www/a/b',
'expected' => 'http://www/a/h/j',
),
array(
'rel' => 'h/j',
'base' => 'http://www/a/b/',
'expected' => 'http://www/a/b/h/j',
),
// Rels that start with "/".
array(
'rel' => '/h',
'base' => 'http://www',
'expected' => 'http://www/h',
),
array(
'rel' => '/h',
'base' => 'http://www/',
'expected' => 'http://www/h',
),
array(
'rel' => '/h',
'base' => 'http://www/?c;d=e#f',
'expected' => 'http://www/h',
),
array(
'rel' => '/h',
'base' => 'http://www/a/b',
'expected' => 'http://www/h',
),
array(
'rel' => '/h/j',
'base' => 'http://www',
'expected' => 'http://www/h/j',
),
array(
'rel' => '/h/j',
'base' => 'http://www/',
'expected' => 'http://www/h/j',
),
array(
'rel' => '/h/j',
'base' => 'http://www/?c;d=e#f',
'expected' => 'http://www/h/j',
),
array(
'rel' => '/h/j',
'base' => 'http://www/a/b',
'expected' => 'http://www/h/j',
),
array(
'rel' => '/h/j',
'base' => 'http://www/a/b/',
'expected' => 'http://www/h/j',
),
// Rels that contain ".".
array(
'rel' => './h',
'base' => 'http://www',
'expected' => 'http://www/h',
),
array(
'rel' => './h',
'base' => 'http://www/',
'expected' => 'http://www/h',
),
array(
'rel' => './h',
'base' => 'http://www/?c;d=e#f',
'expected' => 'http://www/h',
),
array(
'rel' => './h',
'base' => 'http://www/a/b',
'expected' => 'http://www/a/h',
),
array(
'rel' => './h/j',
'base' => 'http://www',
'expected' => 'http://www/h/j',
),
array(
'rel' => './h/j',
'base' => 'http://www/',
'expected' => 'http://www/h/j',
),
array(
'rel' => './h/j',
'base' => 'http://www/?c;d=e#f',
'expected' => 'http://www/h/j',
),
array(
'rel' => './h/j',
'base' => 'http://www/a/b',
'expected' => 'http://www/a/h/j',
),
array(
'rel' => './h/j',
'base' => 'http://www/a/b/',
'expected' => 'http://www/a/b/h/j',
),
array(
'rel' => 'h/./j',
'base' => 'http://www',
'expected' => 'http://www/h/j',
),
array(
'rel' => 'h/./j',
'base' => 'http://www/',
'expected' => 'http://www/h/j',
),
array(
'rel' => 'h/./j',
'base' => 'http://www/?c;d=e#f',
'expected' => 'http://www/h/j',
),
array(
'rel' => 'h/./j',
'base' => 'http://www/a/b',
'expected' => 'http://www/a/h/j',
),
array(
'rel' => 'h/./j',
'base' => 'http://www/a/b/',
'expected' => 'http://www/a/b/h/j',
),
array(
'rel' => '/h/./j',
'base' => 'http://www',
'expected' => 'http://www/h/j',
),
array(
'rel' => '/h/./j',
'base' => 'http://www/',
'expected' => 'http://www/h/j',
),
array(
'rel' => '/h/./j',
'base' => 'http://www/?c;d=e#f',
'expected' => 'http://www/h/j',
),
array(
'rel' => '/h/./j',
'base' => 'http://www/a/b',
'expected' => 'http://www/h/j',
),
array(
'rel' => '/h/./j',
'base' => 'http://www/a/b/',
'expected' => 'http://www/h/j',
),
// Rels that starts with "../".
array(
'rel' => '../h/j',
'base' => 'http://www',
'expected' => 'http://www/h/j',
),
array(
'rel' => '../h/j',
'base' => 'http://www/',
'expected' => 'http://www/h/j',
),
array(
'rel' => '../h/j',
'base' => 'http://www/?c;d=e#f',
'expected' => 'http://www/h/j',
),
array(
'rel' => '../h/j',
'base' => 'http://www/a/b',
'expected' => 'http://www/h/j',
),
array(
'rel' => '../h/j',
'base' => 'http://www/a/b/',
'expected' => 'http://www/a/h/j',
),
array(
'rel' => '../h/j',
'base' => 'http://www/a/b/c/',
'expected' => 'http://www/a/b/h/j',
),
// Rels that start with "../../".
array(
'rel' => '../../h/j',
'base' => 'http://www',
'expected' => 'http://www/h/j',
),
array(
'rel' => '../../h/j',
'base' => 'http://www/',
'expected' => 'http://www/h/j',
),
array(
'rel' => '../../h/j',
'base' => 'http://www/?c;d=e#f',
'expected' => 'http://www/h/j',
),
array(
'rel' => '../../h/j',
'base' => 'http://www/a/b',
'expected' => 'http://www/h/j',
),
array(
'rel' => '../../h/j',
'base' => 'http://www/a/b/',
'expected' => 'http://www/h/j',
),
array(
'rel' => '../../h/j',
'base' => 'http://www/a/b/c/',
'expected' => 'http://www/a/h/j',
),
array(
'rel' => '../../h/j',
'base' => 'http://www/a/b/c/d',
'expected' => 'http://www/a/h/j',
),
// Crazy rels.
array(
'rel' => 'h/../../j/./k',
'base' => 'http://www/a/b/c/',
'expected' => 'http://www/a/b/j/k',
),
array(
'rel' => 'h/../../j/./k',
'base' => 'http://www/a/b/c/d',
'expected' => 'http://www/a/b/j/k',
),
array(
'rel' => '../../../',
'base' => 'http://www/a/b/c/',
'expected' => 'http://www/',
),
array(
'rel' => 'h/j/k/../../',
'base' => 'http://www/a/b/c/',
'expected' => 'http://www/a/b/c/h',
),
);
foreach ($test_urls as $test_url) {
$result_url = http_request_create_absolute_url($test_url['rel'], $test_url['base']);
$this->assertEqual($test_url['expected'], $result_url, format_string('Creating an absolute URL from base @base and rel @rel resulted into @expected (actual: @actual).', array(
'@actual' => var_export($result_url, TRUE),
'@expected' => var_export($test_url['expected'], TRUE),
'@rel' => var_export($test_url['rel'], TRUE),
'@base' => var_export($test_url['base'], TRUE),
)));
}
}
}

View File

@@ -32,48 +32,103 @@ class ParserCSVTest extends DrupalWebTestCase {
$this->_testSimple();
$this->_testBatching();
$this->_testEncodingConversion();
$this->_testEncodingConversionFailure();
}
/**
* Simple test of parsing functionality.
*/
protected function _testSimple() {
$file = $this->absolutePath() . '/tests/feeds/nodes.csv';
// Pull in the $control_result array.
include $this->absolutePath() . '/tests/feeds/nodes.csv.php';
$iterator = new ParserCSVIterator($file);
$parser = new ParserCSV();
$parser->setDelimiter(',');
$rows = $parser->parse($iterator);
$this->assertFalse($parser->lastLinePos(), t('Parser reports all lines parsed'));
$this->assertEqual(md5(serialize($rows)), md5(serialize($control_result)), t('Parsed result matches control result.'));
$delimiters = $this->getDelimiters();
foreach($delimiters as $delimiterType => $delimiter) {
$file = $this->absolutePath() . '/tests/feeds/nodes_' . $delimiterType . '.csv';
$iterator = new ParserCSVIterator($file);
$parser = new ParserCSV();
$parser->setDelimiter($delimiter);
$rows = $parser->parse($iterator);
$this->assertFalse($parser->lastLinePos(), t('CSV reports all lines parsed, with delimiter: ') . $delimiterType);
$this->assertEqual(md5(serialize($rows)), md5(serialize($control_result)), t('Parsed result matches control result.'));
}
}
/**
* Simple test of encoding conversion prior to parsing.
*/
protected function _testEncodingConversion() {
// Pull in the $control_result array.
include $this->absolutePath() . '/tests/feeds/encoding.csv.php';
$encodings = $this->getEncodings();
foreach ($encodings as $encoding) {
$file = $this->absolutePath() . "/tests/feeds/encoding_{$encoding}.csv";
$iterator = new ParserCSVIterator($file);
$parser = new ParserCSV();
$parser->setDelimiter(',');
$parser->setEncoding($encoding);
$rows = $parser->parse($iterator);
$this->assertFalse($parser->lastLinePos(), format_string('CSV reports all lines parsed, with encoding: %encoding', array('%encoding' => $encoding)));
$this->assertEqual(md5(serialize($rows)), md5(serialize($control_result)), 'Converted and parsed result matches control result.');
}
}
/**
* Simple test of failed encoding conversion prior to parsing.
*/
protected function _testEncodingConversionFailure() {
// Pull in the $control_result array.
include $this->absolutePath() . '/tests/feeds/encoding.csv.php';
$encodings = $this->getEncodings();
foreach ($encodings as $encoding) {
$file = $this->absolutePath() . "/tests/feeds/encoding_{$encoding}.csv";
$iterator = new ParserCSVIterator($file);
$parser = new ParserCSV();
$parser->setDelimiter(',');
// Attempt to read file as UTF-8.
$parser->setEncoding('UTF-8');
try {
$rows = $parser->parse($iterator);
$this->fail('Incorrect conversion attempt throws exception.');
}
catch (ParserCSVEncodingException $e) {
$this->assertNotNull($e->getMessage(), 'Incorrect conversion attempt throws exception.');
}
}
}
/**
* Test batching.
*/
protected function _testBatching() {
$file = $this->absolutePath() . '/tests/feeds/nodes.csv';
// Pull in the $control_result array
include $this->absolutePath() . '/tests/feeds/nodes.csv.php';
// Set up parser with 2 lines to parse per call.
$iterator = new ParserCSVIterator($file);
$parser = new ParserCSV();
$parser->setDelimiter(',');
$parser->setLineLimit(2);
$rows = array();
$pos = 0;
$delimiters = $this->getDelimiters();
foreach($delimiters as $delimiterType => $delimiter) {
$file = $this->absolutePath() . '/tests/feeds/nodes_' . $delimiterType . '.csv';
// Set up parser with 2 lines to parse per call.
$iterator = new ParserCSVIterator($file);
$parser = new ParserCSV();
$parser->setDelimiter($delimiter);
$parser->setLineLimit(2);
$rows = array();
$pos = 0;
// Call parser until all lines are parsed, then compare to control result.
do {
$parser->setStartByte($pos);
$rows = array_merge($rows, $parser->parse($iterator));
$pos = $parser->lastLinePos();
$this->assertTrue($parser->lastLinePos() || count($rows) == 10, t('Parser reports line limit correctly'));
// Call parser until all lines are parsed, then compare to control result.
do {
$parser->setStartByte($pos);
$rows = array_merge($rows, $parser->parse($iterator));
$pos = $parser->lastLinePos();
$this->assertTrue($parser->lastLinePos() || count($rows) == 10, t('Parser reports line limit correctly'));
}
while ($pos = $parser->lastLinePos());
$this->assertEqual(md5(serialize($rows)), md5(serialize($control_result)), t('Batch parsed result matches control result for delimiter: ') . $delimiterType);
}
while ($pos = $parser->lastLinePos());
$this->assertEqual(md5(serialize($rows)), md5(serialize($control_result)), t('Parsed result matches control result.'));
}
/**
@@ -82,4 +137,21 @@ class ParserCSVTest extends DrupalWebTestCase {
public function absolutePath() {
return DRUPAL_ROOT . '/' . drupal_get_path('module', 'feeds');
}
static function getDelimiters() {
return array(
'comma' => ',',
'pipe' => '|',
'semicolon' => ';',
'plus' => '+',
'tab' => "\t",
);
}
static function getEncodings() {
return array(
'SJIS-win',
'SJIS',
);
}
}