Index: modules/aggregator/aggregator.parser.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.parser.inc,v
retrieving revision 1.9
diff -u -p -r1.9 aggregator.parser.inc
--- modules/aggregator/aggregator.parser.inc	20 May 2010 08:51:24 -0000	1.9
+++ modules/aggregator/aggregator.parser.inc	16 Jul 2010 18:13:18 -0000
@@ -177,7 +177,6 @@ function aggregator_element_start($parse
   switch ($name) {
     case 'image':
     case 'textinput':
-    case 'content':
     case 'summary':
     case 'tagline':
     case 'subtitle':
@@ -186,16 +185,20 @@ function aggregator_element_start($parse
       $element = $name;
       break;
     case 'id':
+    case 'content':
       if ($element != 'item') {
         $element = $name;
       }
     case 'link':
-      if (!empty($attributes['rel']) && $attributes['rel'] == 'alternate') {
+      // According to RFC 4287, link elements in Atom feeds without a 'rel'
+      // attribute should be interpreted as though the relation type is
+      // "alternate".
+      if (!empty($attributes['HREF']) && (empty($attributes['REL']) || $attributes['REL'] == 'alternate')) {
         if ($element == 'item') {
-          $items[$item]['link'] = $attributes['href'];
+          $items[$item]['link'] = $attributes['HREF'];
         }
         else {
-          $channel['link'] = $attributes['href'];
+          $channel['link'] = $attributes['HREF'];
         }
       }
       break;
@@ -223,12 +226,12 @@ function aggregator_element_end($parser,
     case 'textinput':
     case 'item':
     case 'entry':
-    case 'content':
     case 'info':
       $element = '';
       break;
     case 'id':
-      if ($element == 'id') {
+    case 'content':
+      if ($element == $name) {
         $element = '';
       }
   }
Index: modules/aggregator/aggregator.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.test,v
retrieving revision 1.39
diff -u -p -r1.39 aggregator.test
--- modules/aggregator/aggregator.test	24 Mar 2010 08:51:42 -0000	1.39
+++ modules/aggregator/aggregator.test	16 Jul 2010 18:13:18 -0000
@@ -248,6 +248,12 @@ EOF;
     return $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'aggregator') . '/tests/aggregator_test_rss091.xml';
   }
 
+  function getAtomSample() {
+    // The content of this sample ATOM feed is based directly off of the
+    // example provided in RFC 4287.
+    return $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'aggregator') . '/tests/aggregator_test_atom.xml';
+  }
+
   function createSampleNodes() {
     $langcode = LANGUAGE_NONE;
     // Post 5 articles.
@@ -686,3 +692,51 @@ class AggregatorCronTestCase extends Agg
     $this->assertEqual(5, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.');
   }
 }
+
+/**
+ * Tests for feed parsing.
+ */
+class FeedParserTestCase extends AggregatorTestCase {
+  function getInfo() {
+    return array(
+      'name' => 'Feed parser functionality',
+      'description' => 'Test the built-in feed parser with valid feed samples.',
+      'group' => 'Aggregator',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    // Do not remove old aggregator items during these tests, since our sample
+    // feeds have hardcoded dates in them (which may be expired when this test
+    // is run).
+    variable_set('aggregator_clear', AGGREGATOR_CLEAR_NEVER);
+  }
+
+  /**
+   * Test a feed that uses the RSS 0.91 format.
+   */
+  function testRSS091Sample() {
+    $feed = $this->createFeed($this->getRSS091Sample());
+    aggregator_refresh($feed);
+    $this->drupalGet('aggregator/sources/' . $feed->fid);
+    $this->assertResponse(200, t('Feed %name exists.', array('%name' => $feed->title)));
+    $this->assertText('First example feed item title');
+    $this->assertLinkByHref('http://example.com/example-turns-one');
+    $this->assertText('First example feed item description.');
+  }
+
+  /**
+   * Test a feed that uses the Atom format.
+   */
+  function testAtomSample() {
+    $feed = $this->createFeed($this->getAtomSample());
+    aggregator_refresh($feed);
+    $this->drupalGet('aggregator/sources/' . $feed->fid);
+    $this->assertResponse(200, t('Feed %name exists.', array('%name' => $feed->title)));
+    $this->assertText('Atom-Powered Robots Run Amok');
+    $this->assertLinkByHref('http://example.org/2003/12/13/atom03');
+    $this->assertText('Some text.');
+  }
+}
+
Index: modules/aggregator/tests/aggregator_test_atom.xml
===================================================================
RCS file: modules/aggregator/tests/aggregator_test_atom.xml
diff -N modules/aggregator/tests/aggregator_test_atom.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/aggregator/tests/aggregator_test_atom.xml	16 Jul 2010 18:13:18 -0000
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+  <title>Example Feed</title>
+  <link href="http://example.org/" />
+  <updated>2003-12-13T18:30:02Z</updated>
+  <author>
+    <name>John Doe</name>
+  </author>
+  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+  <entry>
+    <title>Atom-Powered Robots Run Amok</title>
+    <link href="http://example.org/2003/12/13/atom03" />
+    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+    <updated>2003-12-13T18:30:02Z</updated>
+    <summary>Some text.</summary>
+  </entry>
+
+</feed>
Index: modules/aggregator/tests/aggregator_test_rss091.xml
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/tests/aggregator_test_rss091.xml,v
retrieving revision 1.1
diff -u -p -r1.1 aggregator_test_rss091.xml
--- modules/aggregator/tests/aggregator_test_rss091.xml	2 Apr 2009 20:50:37 -0000	1.1
+++ modules/aggregator/tests/aggregator_test_rss091.xml	16 Jul 2010 18:13:18 -0000
@@ -17,14 +17,14 @@
       <description>Example updates</description>
     </image>
     <item>
-      <title>Example turns one</title>
+      <title>First example feed item title</title>
       <link>http://example.com/example-turns-one</link>
-      <description>Example turns one.</description>
+      <description>First example feed item description.</description>
     </item>
     <item>
-      <title>Example turns two</title>
+      <title>Second example feed item title</title>
       <link>http://example.com/example-turns-two</link>
-      <description>Example turns two.</description>
+      <description>Second example feed item description.</description>
     </item>
   </channel>
-</rss>
\ No newline at end of file
+</rss>
