home | career | drupal | java | mac | mysql | perl | php | scala | uml | unix

Drupal example source code file (aggregator.test)

This example Drupal source code file (aggregator.test) is included in the DevDaily.com "Drupal Source Code Warehouse" project. The intent of this project is to help you "Learn Drupal by Example".

PHP - Drupal tags/keywords

aggregator, array, category, count, edit, feed, fid, from, function, name, php, return, title, url

The aggregator.test Drupal example source code

<?php
// $Id: aggregator.test,v 1.47 2010/10/25 15:51:21 webchick Exp $

/**
 * @file
 * Creates tests for aggregator module.
 */

class AggregatorTestCase extends DrupalWebTestCase {
  function setUp() {
    parent::setUp('aggregator', 'aggregator_test');
    $web_user = $this->drupalCreateUser(array('administer news feeds', 'access news feeds', 'create article content'));
    $this->drupalLogin($web_user);
  }

  /**
   * Create an aggregator feed (simulate form submission on admin/config/services/aggregator/add/feed).
   *
   * @param $feed_url
   *   If given, feed will be created with this URL, otherwise /rss.xml will be used.
   * @return $feed
   *   Full feed object if possible.
   *
   * @see getFeedEditArray()
   */
  function createFeed($feed_url = NULL) {
    $edit = $this->getFeedEditArray($feed_url);
    $this->drupalPost('admin/config/services/aggregator/add/feed', $edit, t('Save'));
    $this->assertRaw(t('The feed %name has been added.', array('%name' => $edit['title'])), t('The feed !name has been added.', array('!name' => $edit['title'])));

    $feed = db_query("SELECT *  FROM {aggregator_feed} WHERE title = :title AND url = :url", array(':title' => $edit['title'], ':url' => $edit['url']))->fetch();
    $this->assertTrue(!empty($feed), t('The feed found in database.'));
    return $feed;
  }

  /**
   * Delete an aggregator feed.
   *
   * @param $feed
   *   Feed object representing the feed.
   */
  function deleteFeed($feed) {
    $this->drupalPost('admin/config/services/aggregator/edit/feed/' . $feed->fid, array(), t('Delete'));
    $this->assertRaw(t('The feed %title has been deleted.', array('%title' => $feed->title)), t('Feed deleted successfully.'));
  }

  /**
   * Return a randomly generated feed edit array.
   *
   * @param $feed_url
   *   If given, feed will be created with this URL, otherwise /rss.xml will be used.
   * @return
   *   A feed array.
   */
  function getFeedEditArray($feed_url = NULL) {
    $feed_name = $this->randomName(10);
    if (!$feed_url) {
      $feed_url = url('rss.xml', array(
        'query' => array('feed' => $feed_name),
        'absolute' => TRUE,
      ));
    }
    $edit = array(
      'title' => $feed_name,
      'url' => $feed_url,
      'refresh' => '900',
    );
    return $edit;
  }

  /**
   * Return the count of the randomly created feed array.
   *
   * @return
   *   Number of feed items on default feed created by createFeed().
   */
  function getDefaultFeedItemCount() {
    // Our tests are based off of rss.xml, so let's find out how many elements should be related.
    $feed_count = db_query_range('SELECT COUNT(*) FROM {node} n WHERE n.promote = 1 AND n.status = 1', 0, variable_get('feed_default_items', 10))->fetchField();
    return $feed_count > 10 ? 10 : $feed_count;
  }

  /**
   * Update feed items (simulate click to admin/config/services/aggregator/update/$fid).
   *
   * @param $feed
   *   Feed object representing the feed.
   * @param $expected_count
   *   Expected number of feed items.
   */
  function updateFeedItems(&$feed, $expected_count) {
    // First, let's ensure we can get to the rss xml.
    $this->drupalGet($feed->url);
    $this->assertResponse(200, t('!url is reachable.', array('!url' => $feed->url)));

    // Refresh the feed (simulated link click).
    $this->drupalGet('admin/config/services/aggregator/update/' . $feed->fid);

    // Ensure we have the right number of items.
    $result = db_query('SELECT iid FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid));
    $items = array();
    $feed->items = array();
    foreach ($result as $item) {
      $feed->items[] = $item->iid;
    }
    $feed->item_count = count($feed->items);
    $this->assertEqual($expected_count, $feed->item_count, t('Total items in feed equal to the total items in database (!val1 != !val2)', array('!val1' => $expected_count, '!val2' => $feed->item_count)));
  }

  /**
   * Confirm item removal from a feed.
   *
   * @param $feed
   *   Feed object representing the feed.
   */
  function removeFeedItems($feed) {
    $this->drupalPost('admin/config/services/aggregator/remove/' . $feed->fid, array(), t('Remove items'));
    $this->assertRaw(t('The news items from %title have been removed.', array('%title' => $feed->title)), t('Feed items removed.'));
  }

  /**
   * Add and remove feed items and ensure that the count is zero.
   *
   * @param $feed
   *   Feed object representing the feed.
   * @param $expected_count
   *   Expected number of feed items.
   */
  function updateAndRemove($feed, $expected_count) {
    $this->updateFeedItems($feed, $expected_count);
    $count = db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField();
    $this->assertTrue($count);
    $this->removeFeedItems($feed);
    $count = db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField();
    $this->assertTrue($count == 0);
  }

  /**
   * Pull feed categories from aggregator_category_feed table.
   *
   * @param $feed
   *   Feed object representing the feed.
   */
  function getFeedCategories($feed) {
    // add the categories to the feed so we can use them
    $result = db_query('SELECT cid FROM {aggregator_category_feed} WHERE fid = :fid', array(':fid' => $feed->fid));
    foreach ($result as $category) {
      $feed->categories[] = $category->cid;
    }
  }

  /**
   * Pull categories from aggregator_category table.
   */
  function getCategories() {
    $categories = array();
    $result = db_query('SELECT * FROM {aggregator_category}');
    foreach ($result as $category) {
      $categories[$category->cid] = $category;
    }
    return $categories;
  }


  /**
   * Check if the feed name and url is unique.
   *
   * @param $feed_name
   *   String containing the feed name to check.
   * @param $feed_url
   *   String containing the feed url to check.
   * @return
   *   TRUE if feed is unique.
   */
  function uniqueFeed($feed_name, $feed_url) {
    $result = db_query("SELECT COUNT(*) FROM {aggregator_feed} WHERE title = :title AND url = :url", array(':title' => $feed_name, ':url' => $feed_url))->fetchField();
    return (1 == $result);
  }

  /**
   * Create a valid OPML file from an array of feeds.
   *
   * @param $feeds
   *   An array of feeds.
   * @return
   *   Path to valid OPML file.
   */
  function getValidOpml($feeds) {
    // Properly escape URLs so that XML parsers don't choke on them.
    foreach ($feeds as &$feed) {
      $feed['url'] = htmlspecialchars($feed['url']);
    }
    /**
     * Does not have an XML declaration, must pass the parser.
     */
    $opml = <<<EOF
<opml version="1.0">
  <head></head>
  <body>
    <!-- First feed to be imported. -->
    <outline text="{$feeds[0]['title']}" xmlurl="{$feeds[0]['url']}" />

    <!-- Second feed. Test string delimitation and attribute order. -->
    <outline xmlurl='{$feeds[1]['url']}' text='{$feeds[1]['title']}'/>

    <!-- Test for duplicate URL and title. -->
    <outline xmlurl="{$feeds[0]['url']}" text="Duplicate URL"/>
    <outline xmlurl="http://duplicate.title" text="{$feeds[1]['title']}"/>

    <!-- Test that feeds are only added with required attributes. -->
    <outline text="{$feeds[2]['title']}" />
    <outline xmlurl="{$feeds[2]['url']}" />
  </body>
</opml>
EOF;

    $path = 'public://valid-opml.xml';
    return file_unmanaged_save_data($opml, $path);
  }

  /**
   * Create an invalid OPML file.
   *
   * @return
   *   Path to invalid OPML file.
   */
  function getInvalidOpml() {
    $opml = <<<EOF
<opml>
  <invalid>
</opml>
EOF;

    $path = 'public://invalid-opml.xml';
    return file_unmanaged_save_data($opml, $path);
  }

  /**
   * Create a valid but empty OPML file.
   *
   * @return
   *   Path to empty OPML file.
   */
  function getEmptyOpml() {
    $opml = <<<EOF
<?xml version="1.0" encoding="utf-8"?>
<opml version="1.0">
  <head></head>
  <body>
    <outline text="Sample text" />
    <outline text="Sample text" url="Sample URL" />
  </body>
</opml>
EOF;

    $path = 'public://empty-opml.xml';
    return file_unmanaged_save_data($opml, $path);
  }

  function getRSS091Sample() {
    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.
    for ($i = 0; $i < 5; $i++) {
      $edit = array();
      $edit['title'] = $this->randomName();
      $edit["body[$langcode][0][value]"] = $this->randomName();
      $this->drupalPost('node/add/article', $edit, t('Save'));
    }
  }
}

class AddFeedTestCase extends AggregatorTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Add feed functionality',
      'description' => 'Add feed test.',
      'group' => 'Aggregator'
    );
  }

  /**
   * Create a feed, ensure that it is unique, check the source, and delete the feed.
   */
  function testAddFeed() {
    $feed = $this->createFeed();

    // Check feed data.
    $this->assertEqual($this->getUrl(), url('admin/config/services/aggregator/add/feed', array('absolute' => TRUE)), t('Directed to correct url.'));
    $this->assertTrue($this->uniqueFeed($feed->title, $feed->url), t('The feed is unique.'));

    // Check feed source.
    $this->drupalGet('aggregator/sources/' . $feed->fid);
    $this->assertResponse(200, t('Feed source exists.'));
    $this->assertText($feed->title, t('Page title'));
    $this->drupalGet('aggregator/sources/' . $feed->fid . '/categorize');
    $this->assertResponse(200, t('Feed categorization page exists.'));

    // Delete feed.
    $this->deleteFeed($feed);
  }
}

class CategorizeFeedTestCase extends AggregatorTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Categorize feed functionality',
      'description' => 'Categorize feed test.',
      'group' => 'Aggregator'
    );
  }

  /**
   * Create a feed and make sure you can add more than one category to it.
   */
  function testCategorizeFeed() {

    // Create 2 categories.
    $category_1 = array('title' => $this->randomName(10), 'description' => '');
    $this->drupalPost('admin/config/services/aggregator/add/category', $category_1, t('Save'));
    $this->assertRaw(t('The category %title has been added.', array('%title' => $category_1['title'])), t('The category %title has been added.', array('%title' => $category_1['title'])));

    $category_2 = array('title' => $this->randomName(10), 'description' => '');
    $this->drupalPost('admin/config/services/aggregator/add/category', $category_2, t('Save'));
    $this->assertRaw(t('The category %title has been added.', array('%title' => $category_2['title'])), t('The category %title has been added.', array('%title' => $category_2['title'])));

    // Get categories from database.
    $categories = $this->getCategories();

    // Create a feed and assign 2 categories to it.
    $feed = $this->getFeedEditArray();
    $feed['block'] = 5;
    foreach ($categories as $cid => $category) {
      $feed['category'][$cid] = $cid;
    }

    // Use aggregator_save_feed() function to save the feed.
    aggregator_save_feed($feed);
    $db_feed = db_query("SELECT *  FROM {aggregator_feed} WHERE title = :title AND url = :url", array(':title' => $feed['title'], ':url' => $feed['url']))->fetch();

    // Assert the feed has two categories.
    $this->getFeedCategories($db_feed);
    $this->assertEqual(count($db_feed->categories), 2, t('Feed has 2 categories'));
  }
}

class UpdateFeedTestCase extends AggregatorTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Update feed functionality',
      'description' => 'Update feed test.',
      'group' => 'Aggregator'
    );
  }

  /**
   * Create a feed and attempt to update it.
   */
  function testUpdateFeed() {
    $remamining_fields = array('title', 'url', '');
    foreach ($remamining_fields as $same_field) {
      $feed = $this->createFeed();

      // Get new feed data array and modify newly created feed.
      $edit = $this->getFeedEditArray();
      $edit['refresh'] =  1800; // Change refresh value.
      if (isset($feed->{$same_field})) {
        $edit[$same_field] = $feed->{$same_field};
      }
      $this->drupalPost('admin/config/services/aggregator/edit/feed/' . $feed->fid, $edit, t('Save'));
      $this->assertRaw(t('The feed %name has been updated.', array('%name' => $edit['title'])), t('The feed %name has been updated.', array('%name' => $edit['title'])));

      // Check feed data.
      $this->assertEqual($this->getUrl(), url('admin/config/services/aggregator/', array('absolute' => TRUE)));
      $this->assertTrue($this->uniqueFeed($edit['title'], $edit['url']), t('The feed is unique.'));

      // Check feed source.
      $this->drupalGet('aggregator/sources/' . $feed->fid);
      $this->assertResponse(200, t('Feed source exists.'));
      $this->assertText($edit['title'], t('Page title'));

      // Delete feed.
      $feed->title = $edit['title']; // Set correct title so deleteFeed() will work.
      $this->deleteFeed($feed);
    }
  }
}

class RemoveFeedTestCase extends AggregatorTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Remove feed functionality',
      'description' => 'Remove feed test.',
      'group' => 'Aggregator'
    );
  }

  /**
   * Remove a feed and ensure that all it services are removed.
   */
  function testRemoveFeed() {
    $feed = $this->createFeed();

    // Delete feed.
    $this->deleteFeed($feed);

    // Check feed source.
    $this->drupalGet('aggregator/sources/' . $feed->fid);
    $this->assertResponse(404, t('Deleted feed source does not exists.'));

    // Check database for feed.
    $result = db_query("SELECT COUNT(*) FROM {aggregator_feed} WHERE title = :title AND url = :url", array(':title' => $feed->title, ':url' => $feed->url))->fetchField();
    $this->assertFalse($result, t('Feed not found in database'));
  }
}

class UpdateFeedItemTestCase extends AggregatorTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Update feed item functionality',
      'description' => 'Update feed items from a feed.',
      'group' => 'Aggregator'
    );
  }

  /**
   * Test running "update items" from the 'admin/config/services/aggregator' page.
   */
  function testUpdateFeedItem() {
    $this->createSampleNodes();

    // Create a feed and test updating feed items if possible.
    $feed = $this->createFeed();
    if (!empty($feed)) {
      $this->updateFeedItems($feed, $this->getDefaultFeedItemCount());
      $this->removeFeedItems($feed);
    }

    // Delete feed.
    $this->deleteFeed($feed);

    // Test updating feed items without valid timestamp information.
    $edit = array(
      'title' => "Feed without publish timestamp",
      'url' => $this->getRSS091Sample(),
    );

    $this->drupalGet($edit['url']);
    $this->assertResponse(array(200), t('URL !url is accessible', array('!url' => $edit['url'])));

    $this->drupalPost('admin/config/services/aggregator/add/feed', $edit, t('Save'));
    $this->assertRaw(t('The feed %name has been added.', array('%name' => $edit['title'])), t('The feed !name has been added.', array('!name' => $edit['title'])));

    $feed = db_query("SELECT * FROM {aggregator_feed} WHERE url = :url", array(':url' => $edit['url']))->fetchObject();
    $this->drupalGet('admin/config/services/aggregator/update/' . $feed->fid);

    $before = db_query('SELECT timestamp FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField();

    // Sleep for 3 second.
    sleep(3);
    db_update('aggregator_feed')
      ->condition('fid', $feed->fid)
      ->fields(array(
        'checked' => 0,
        'hash' => '',
        'etag' => '',
        'modified' => 0,
      ))
      ->execute();
    $this->drupalGet('admin/config/services/aggregator/update/' . $feed->fid);

    $after = db_query('SELECT timestamp FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField();

    $this->assertTrue($before === $after, t('Publish timestamp of feed item was not updated (!before === !after)', array('!before' => $before, '!after' => $after)));
  }
}

class RemoveFeedItemTestCase extends AggregatorTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Remove feed item functionality',
      'description' => 'Remove feed items from a feed.',
      'group' => 'Aggregator'
    );
  }

  /**
   * Test running "remove items" from the 'admin/config/services/aggregator' page.
   */
  function testRemoveFeedItem() {
    // Create a bunch of test feeds.
    $feed_urls = array();
    // No last-modified, no etag.
    $feed_urls[] = url('aggregator/test-feed', array('absolute' => TRUE));
    // Last-modified, but no etag.
    $feed_urls[] = url('aggregator/test-feed/1', array('absolute' => TRUE));
    // No Last-modified, but etag.
    $feed_urls[] = url('aggregator/test-feed/0/1', array('absolute' => TRUE));
    // Last-modified and etag.
    $feed_urls[] = url('aggregator/test-feed/1/1', array('absolute' => TRUE));

    foreach ($feed_urls as $feed_url) {
      $feed = $this->createFeed($feed_url);
      // Update and remove items two times in a row to make sure that removal
      // resets all 'modified' information (modified, etag, hash) and allows for
      // immediate update.
      $this->updateAndRemove($feed, 2);
      $this->updateAndRemove($feed, 2);
      $this->updateAndRemove($feed, 2);
      // Delete feed.
      $this->deleteFeed($feed);
    }
  }
}

class CategorizeFeedItemTestCase extends AggregatorTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Categorize feed item functionality',
      'description' => 'Test feed item categorization.',
      'group' => 'Aggregator'
    );
  }

  /**
   * If a feed has a category, make sure that the children inherit that
   * categorization.
   */
  function testCategorizeFeedItem() {
    $this->createSampleNodes();

    // Simulate form submission on "admin/config/services/aggregator/add/category".
    $edit = array('title' => $this->randomName(10), 'description' => '');
    $this->drupalPost('admin/config/services/aggregator/add/category', $edit, t('Save'));
    $this->assertRaw(t('The category %title has been added.', array('%title' => $edit['title'])), t('The category %title has been added.', array('%title' => $edit['title'])));

    $category = db_query("SELECT * FROM {aggregator_category} WHERE title = :title", array(':title' => $edit['title']))->fetch();
    $this->assertTrue(!empty($category), t('The category found in database.'));

    $link_path = 'aggregator/categories/' . $category->cid;
    $menu_link = db_query("SELECT * FROM {menu_links} WHERE link_path = :link_path", array(':link_path' => $link_path))->fetch();
    $this->assertTrue(!empty($menu_link), t('The menu link associated with the category found in database.'));

    $feed = $this->createFeed();
    db_insert('aggregator_category_feed')
      ->fields(array(
        'cid' => $category->cid,
        'fid' => $feed->fid,
      ))
      ->execute();
    $this->updateFeedItems($feed, $this->getDefaultFeedItemCount());
    $this->getFeedCategories($feed);
    $this->assertTrue(!empty($feed->categories), t('The category found in the feed.'));

    // For each category of a feed, ensure feed items have that category, too.
    if (!empty($feed->categories) && !empty($feed->items)) {
      foreach ($feed->categories as $category) {
        $categorized_count = db_select('aggregator_category_item')
          ->condition('iid', $feed->items, 'IN')
          ->countQuery()
          ->execute()
          ->fetchField();

        $this->assertEqual($feed->item_count, $categorized_count, t('Total items in feed equal to the total categorized feed items in database'));
      }
    }

    // Delete feed.
    $this->deleteFeed($feed);
  }
}

class ImportOPMLTestCase extends AggregatorTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Import feeds from OPML functionality',
      'description' => 'Test OPML import.',
      'group' => 'Aggregator',
    );
  }

  /**
   * Open OPML import form.
   */
  function openImportForm() {
    db_delete('aggregator_category')->execute();

    $category = $this->randomName(10);
    $cid = db_insert('aggregator_category')
      ->fields(array(
        'title' => $category,
        'description' => '',
      ))
      ->execute();

    $this->drupalGet('admin/config/services/aggregator/add/opml');
    $this->assertText('A single OPML document may contain a collection of many feeds.', t('Found OPML help text.'));
    $this->assertField('files[upload]', t('Found file upload field.'));
    $this->assertField('remote', t('Found Remote URL field.'));
    $this->assertField('refresh', '', t('Found Refresh field.'));
    $this->assertFieldByName("category[$cid]", $cid, t('Found category field.'));
  }

  /**
   * Submit form filled with invalid fields.
   */
  function validateImportFormFields() {
    $before = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();

    $edit = array();
    $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
    $this->assertRaw(t('You must <em>either</em> upload a file or enter a URL.'), t('Error if no fields are filled.'));

    $path = $this->getEmptyOpml();
    $edit = array(
      'files[upload]' => $path,
      'remote' => file_create_url($path),
    );
    $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
    $this->assertRaw(t('You must <em>either</em> upload a file or enter a URL.'), t('Error if both fields are filled.'));

    $edit = array('remote' => 'invalidUrl://empty');
    $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
    $this->assertText(t('This URL is not valid.'), t('Error if the URL is invalid.'));

    $after = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
    $this->assertEqual($before, $after, t('No feeds were added during the three last form submissions.'));
  }

  /**
   * Submit form with invalid, empty and valid OPML files.
   */
  function submitImportForm() {
    $before = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();

    $form['files[upload]'] = $this->getInvalidOpml();
    $this->drupalPost('admin/config/services/aggregator/add/opml', $form, t('Import'));
    $this->assertText(t('No new feed has been added.'), t('Attempting to upload invalid XML.'));

    $edit = array('remote' => file_create_url($this->getEmptyOpml()));
    $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
    $this->assertText(t('No new feed has been added.'), t('Attempting to load empty OPML from remote URL.'));

    $after = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
    $this->assertEqual($before, $after, t('No feeds were added during the two last form submissions.'));

    db_delete('aggregator_feed')->execute();
    db_delete('aggregator_category')->execute();
    db_delete('aggregator_category_feed')->execute();

    $category = $this->randomName(10);
    db_insert('aggregator_category')
      ->fields(array(
        'cid' => 1,
        'title' => $category,
        'description' => '',
      ))
      ->execute();

    $feeds[0] = $this->getFeedEditArray();
    $feeds[1] = $this->getFeedEditArray();
    $feeds[2] = $this->getFeedEditArray();
    $edit = array(
      'files[upload]' => $this->getValidOpml($feeds),
      'refresh'       => '900',
      'category[1]'   => $category,
    );
    $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
    $this->assertRaw(t('A feed with the URL %url already exists.', array('%url' => $feeds[0]['url'])), t('Verifying that a duplicate URL was identified'));
    $this->assertRaw(t('A feed named %title already exists.', array('%title' => $feeds[1]['title'])), t('Verifying that a duplicate title was identified'));

    $after = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
    $this->assertEqual($after, 2, t('Verifying that two distinct feeds were added.'));

    $feeds_from_db = db_query("SELECT f.title, f.url, f.refresh, cf.cid FROM {aggregator_feed} f LEFT JOIN {aggregator_category_feed} cf ON f.fid = cf.fid");
    $refresh = $category = TRUE;
    foreach ($feeds_from_db as $feed) {
      $title[$feed->url] = $feed->title;
      $url[$feed->title] = $feed->url;
      $category = $category && $feed->cid == 1;
      $refresh = $refresh && $feed->refresh == 900;
    }

    $this->assertEqual($title[$feeds[0]['url']], $feeds[0]['title'], t('First feed was added correctly.'));
    $this->assertEqual($url[$feeds[1]['title']], $feeds[1]['url'], t('Second feed was added correctly.'));
    $this->assertTrue($refresh, t('Refresh times are correct.'));
    $this->assertTrue($category, t('Categories are correct.'));
  }

  function testOPMLImport() {
    $this->openImportForm();
    $this->validateImportFormFields();
    $this->submitImportForm();
  }
}

class AggregatorCronTestCase extends AggregatorTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Update on cron functionality',
      'description' => 'Update feeds on cron.',
      'group' => 'Aggregator'
    );
  }

  /**
   * Add feeds update them on cron.
   */
  public function testCron() {
    // Create feed and test basic updating on cron.
    global $base_url;
    $key = variable_get('cron_key', 'drupal');
    $this->createSampleNodes();
    $feed = $this->createFeed();
    $this->drupalGet($base_url . '/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key)));
    $this->assertEqual(5, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.');
    $this->removeFeedItems($feed);
    $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.');
    $this->drupalGet($base_url . '/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key)));
    $this->assertEqual(5, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.');

    // Test feed locking when queued for update.
    $this->removeFeedItems($feed);
    db_update('aggregator_feed')
      ->condition('fid', $feed->fid)
      ->fields(array(
        'queued' => REQUEST_TIME,
      ))
      ->execute();
    $this->drupalGet($base_url . '/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key)));
    $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.');
    db_update('aggregator_feed')
      ->condition('fid', $feed->fid)
      ->fields(array(
        'queued' => 0,
      ))
      ->execute();
    $this->drupalGet($base_url . '/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key)));
    $this->assertEqual(5, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.');
  }
}

class AggregatorRenderingTestCase extends AggregatorTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Checks display of aggregator items',
      'description' => 'Checks display of aggregator items on the page.',
      'group' => 'Aggregator'
    );
  }

  /**
   * Add a feed block to the page and checks its links.
   *
   * TODO: Test the category block as well.
   */
  public function testBlockLinks() {
    // Create feed.
    $this->createSampleNodes();
    $feed = $this->createFeed();
    $this->updateFeedItems($feed, $this->getDefaultFeedItemCount());

    // Place block on page (@see block.test:moveBlockToRegion())
    // Need admin user to be able to access block admin.
    $this->admin_user = $this->drupalCreateUser(array(
      'administer blocks',
      'access administration pages',
      'administer news feeds',
      'access news feeds',
    ));
    $this->drupalLogin($this->admin_user);

    // Prepare to use the block admin form.
    $block = array(
      'module' => 'aggregator',
      'delta' => 'feed-' . $feed->fid,
      'title' => $feed->title,
    );
    $region = 'footer';
    $edit = array();
    $edit['blocks[' . $block['module'] . '_' . $block['delta'] . '][region]'] = $region;
    // Check the feed block is available in the block list form.
    $this->drupalGet('admin/structure/block');
    $this->assertFieldByName('blocks[' . $block['module'] . '_' . $block['delta'] . '][region]', '', 'Aggregator feed block is available for positioning.');
    // Position it.
    $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
    $this->assertText(t('The block settings have been updated.'), t('Block successfully moved to %region_name region.', array( '%region_name' => $region)));
    // Confirm that the block is now being displayed on pages.
    $this->drupalGet('node');
    $this->assertText(t($block['title']), t('Feed block is displayed on the page.'));

    // Find the expected read_more link.
    $href = 'aggregator/sources/' . $feed->fid;
    $links = $this->xpath('//a[@href = :href]', array(':href' => url($href)));
    $this->assert(isset($links[0]), t('Link to href %href found.', array('%href' => $href)));

    // Visit that page.
    $this->drupalGet($href);
    $correct_titles = $this->xpath('//h1[normalize-space(text())=:title]', array(':title' => $feed->title));
    $this->assertFalse(empty($correct_titles), t('Aggregator feed page is available and has the correct title.'));
  }
}

/**
 * Tests for feed parsing.
 */
class FeedParserTestCase extends AggregatorTestCase {
  public static 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.');
  }
}

Other Drupal examples (source code examples)

Here is a short list of links related to this Drupal aggregator.test source code file:

new blog posts

"Drupal" is a registered trademark of Dries Buytaert.

my drupal tutorials and examples  

Copyright 1998-2016 Alvin Alexander, alvinalexander.com
All Rights Reserved.

Beginning in 2016, a portion of the proceeds from pages under the '/drupal-code-examples/' URI will be donated to charity.