Index: modules/filter/filter.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.test,v
retrieving revision 1.41
diff -u -r1.41 filter.test
--- modules/filter/filter.test	12 Sep 2009 06:09:45 -0000	1.41
+++ modules/filter/filter.test	13 Sep 2009 14:23:15 -0000
@@ -14,92 +14,106 @@
    * Test filter administration functionality.
    */
   function testFilterAdmin() {
-    // URL filter.
-    $first_filter = 'filter_url';
-    // Line filter.
-    $second_filter = 'filter_autop';
-
     // Create users.
     $admin_user = $this->drupalCreateUser(array('administer filters'));
     $web_user = $this->drupalCreateUser(array('create page content'));
     $this->drupalLogin($admin_user);
 
-    list($filtered, $full) = $this->checkFilterFormats();
+    $filtered_html = $this->getFormatByName('Filtered HTML');
+    $this->assertTrue($filtered_html->name == 'Filtered HTML', t('Text format Filtered HTML exists'));
+
+    $full_html = $this->getFormatByName('Full HTML');
+    $this->assertTrue($full_html->name == 'Full HTML', t('Text format Filtered HTML exists'));
 
     // Verify access permissions to Full HTML format.
-    $this->assertTrue(filter_access($full, $admin_user), t('Admin user may use Full HTML.'));
-    $this->assertFalse(filter_access($full, $web_user), t('Web user may not use Full HTML.'));
+    $this->assertTrue(filter_access($full_html->format, $admin_user), t('Admin user may use Full HTML.'));
+    $this->assertFalse(filter_access($full_html->format, $web_user), t('Web user may not use Full HTML.'));
 
     // Change default filter.
     $edit = array();
-    $edit['default'] = $full;
+    $edit['default'] = $full_html->format;
     $this->drupalPost('admin/config/content/formats', $edit, t('Save changes'));
     $this->assertText(t('Default format updated.'), t('Default filter updated successfully.'));
 
-    $this->assertNoRaw('admin/config/content/formats/' . $full . '/delete', t('Delete link not found.'));
+    $this->assertNoRaw('admin/config/content/formats/' . $full_html->format . '/delete', t('Delete link not found.'));
 
-    // Add an additional tag.
+    // Test filter configuration for the Filtered HTML format.
     $edit = array();
+    // Add an additional tag.
     $edit['settings[filter_html][allowed_html]'] = '<a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <quote>';
-    $this->drupalPost('admin/config/content/formats/' . $filtered . '/configure', $edit, t('Save configuration'));
+    $this->drupalPost('admin/config/content/formats/' . $filtered_html->format . '/configure', $edit, t('Save configuration'));
     $this->assertText(t('The configuration options have been saved.'), t('Allowed HTML tag added.'));
-
     $this->assertRaw(htmlentities($edit['settings[filter_html][allowed_html]']), t('Tag displayed.'));
+    // Check if the cache was cleared when filter configuration was altered.
+    $this->assertFilterCacheEmpty();
 
-    $result = db_query('SELECT * FROM {cache_filter}')->fetchObject();
-    $this->assertFalse($result, t('Cache cleared.'));
-
-    // Reorder filters.
+    // Reorder filters in Filtered HTML format.
     $edit = array();
-    $edit['weights[' . $second_filter . ']'] = 1;
-    $edit['weights[' . $first_filter . ']'] = 2;
-    $this->drupalPost('admin/config/content/formats/' . $filtered . '/order', $edit, t('Save configuration'));
+    $filters = filter_list_format($filtered_html->format);
+    // Reverse the order of the filters.
+    $filters = array_reverse($filters);
+    foreach (array_keys($filters) as $weight => $name) {
+      $edit['weights[' . $name . ']'] = $weight;
+    }
+    $this->drupalPost('admin/config/content/formats/' . $filtered_html->format . '/order', $edit, t('Save configuration'));
     $this->assertText(t('The filter ordering has been saved.'), t('Order saved successfully.'));
 
-    $result = db_query('SELECT * FROM {filter} WHERE format = :format ORDER BY weight ASC', array(':format' => $filtered));
-    $filters = array();
-    foreach ($result as $filter) {
-      if ($filter->name == $second_filter || $filter->name == $first_filter) {
-        $filters[] = $filter;
-      }
-    }
-    $this->assertTrue(($filters[0]->name == $second_filter && $filters[1]->name == $first_filter), t('Order confirmed.'));
+    // Check if the order saved is the same configured.
+    $filters_ordered = db_query('SELECT name FROM {filter} WHERE format = :format ORDER BY weight ASC', array(':format' => $filtered_html->format))->fetchCol();
+    $this->assertTrue($filters_ordered === array_keys($filters), t('Order saved correctly.'));
+
+    // Check if the cache was cleared when filters were reordered.
+    $this->assertFilterCacheEmpty();
+
+    // Add new text format.
+    $filter_info = filter_get_filters();
+    // Pick random filters to enable, at least 2 filters.
+    $enabled_filters = array_rand($filter_info, mt_rand(2, count($filter_info)));
 
-    // Add filter.
     $edit = array();
     $edit['name'] = $this->randomName();
-    $edit['roles[2]'] = 1;
-    $edit['filters[' . $second_filter . '][status]'] = TRUE;
-    $edit['filters[' . $first_filter . '][status]'] = TRUE;
+    $edit['roles[' . DRUPAL_AUTHENTICATED_RID. ']'] = 1;
+    foreach ($enabled_filters as $name) {
+      $edit['filters[' . $name . '][status]'] = TRUE;
+    }
     $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
-    $this->assertRaw(t('Added text format %format.', array('%format' => $edit['name'])), t('New filter created.'));
+    $this->assertRaw(t('Added text format %format.', array('%format' => $edit['name'])), t('New text format created.'));
+
+    $format = $this->getFormatByName($edit['name']);
+    $this->assertEqual($format->name, $edit['name'], t('Format found in database.'));
 
-    $format = $this->getFilter($edit['name']);
-    $this->assertNotNull($format, t('Format found in database.'));
+    if (!empty($format)) {
+      $this->assertFieldByName('roles[' . DRUPAL_AUTHENTICATED_RID. ']', 1, t('Role found.'));
+      // Check if the enabled filters were saved correctly.
+      $cache = TRUE;
+      foreach ($enabled_filters as $name) {
+        $this->assertFieldByName('filters[' . $name . '][status]', '', t('!name enabled.', array('!name' => $name)));
+        if (isset($filter_info[$name]['cache'])) {
+          $cache &= $filter_info[$name]['cache'];
+        }
+      }
 
-    if ($format !== NULL) {
-      $this->assertFieldByName('roles[2]', '', t('Role found.'));
-      $this->assertFieldByName('filters[' . $second_filter . '][status]', '', t('Line break filter found.'));
-      $this->assertFieldByName('filters[' . $first_filter . '][status]', '', t('Url filter found.'));
+      // Check if the cache property was determined and saved correclty.
+      $this->assertEqual($format->cache, $cache, t('Correctly determined if format allow cache.'));
 
-      // Delete new filter.
+      // Delete the text format.
       $this->drupalPost('admin/config/content/formats/' . $format->format . '/delete', array(), t('Delete'));
       $this->assertRaw(t('Deleted text format %format.', array('%format' => $edit['name'])), t('Format successfully deleted.'));
     }
 
     // Change default filter back.
     $edit = array();
-    $edit['default'] = $filtered;
+    $edit['default'] = $filtered_html->format;
     $this->drupalPost('admin/config/content/formats', $edit, t('Save changes'));
     $this->assertText(t('Default format updated.'), t('Default filter updated successfully.'));
 
-    $this->assertNoRaw('admin/config/content/formats/' . $filtered . '/delete', t('Delete link not found.'));
+    $this->assertNoRaw('admin/config/content/formats/' . $filtered_html->format . '/delete', t('Delete link not found.'));
 
     // Allow authenticated users on full HTML.
     $edit = array();
     $edit['roles[1]'] = 0;
     $edit['roles[2]'] = 1;
-    $this->drupalPost('admin/config/content/formats/' . $full, $edit, t('Save configuration'));
+    $this->drupalPost('admin/config/content/formats/' . $full_html->format, $edit, t('Save configuration'));
     $this->assertText(t('The text format settings have been updated.'), t('Full HTML format successfully updated.'));
 
     // Switch user.
@@ -107,7 +121,7 @@
     $this->drupalLogin($web_user);
 
     $this->drupalGet('node/add/page');
-    $this->assertRaw('<option value="' . $full . '">Full HTML</option>', t('Full HTML filter accessible.'));
+    $this->assertRaw('<option value="' . $full_html->format . '">Full HTML</option>', t('Full HTML filter accessible.'));
 
     // Use filtered HTML and see if it removes tags that are not allowed.
     $body = $this->randomName();
@@ -117,7 +131,7 @@
     $edit['title'] = $this->randomName();
     $langcode = FIELD_LANGUAGE_NONE;
     $edit["body[$langcode][0][value]"] = $body . '<random>' . $extra_text . '</random>';
-    $edit["body[$langcode][0][value_format]"] = $filtered;
+    $edit["body[$langcode][0][value_format]"] = $filtered_html->format;
     $this->drupalPost('node/add/page', $edit, t('Save'));
     $this->assertRaw(t('Page %title has been created.', array('%title' => $edit['title'])), t('Filtered node created.'));
 
@@ -126,65 +140,29 @@
 
     $this->drupalGet('node/' . $node->nid);
     $this->assertText($body . $extra_text, t('Filter removed invalid tag.'));
-
-    // Switch user.
-    $this->drupalLogout();
-    $this->drupalLogin($admin_user);
-
-    // Clean up.
-    // Allowed tags.
-    $edit = array();
-    $edit['settings[filter_html][allowed_html]'] = '<a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>';
-    $this->drupalPost('admin/config/content/formats/' . $filtered . '/configure', $edit, t('Save configuration'));
-    $this->assertText(t('The configuration options have been saved.'), t('Changes reverted.'));
-
-    // Full HTML.
-    $edit = array();
-    $edit['roles[2]'] = FALSE;
-    $this->drupalPost('admin/config/content/formats/' . $full, $edit, t('Save configuration'));
-    $this->assertText(t('The text format settings have been updated.'), t('Full HTML format successfully reverted.'));
-
-    // Filter order.
-    $edit = array();
-    $edit['weights[' . $second_filter . ']'] = 2;
-    $edit['weights[' . $first_filter . ']'] = 1;
-    $this->drupalPost('admin/config/content/formats/' . $filtered . '/order', $edit, t('Save configuration'));
-    $this->assertText(t('The filter ordering has been saved.'), t('Order successfully reverted.'));
   }
 
   /**
-   * Query the database to get the two basic formats.
+   * Get text format by name.
    *
+   * @param $name
+   *   The name of the format.
    * @return
-   *   An array containing filtered and full filter ids.
+   *   A format object as returned by filter_format_load() if a format with the
+   *   given name exists, FALSE otherwise.
    */
-  function checkFilterFormats() {
-    $result = db_query('SELECT format, name FROM {filter_format}');
-
-    $filtered = -1;
-    $full = -1;
-    foreach ($result as $format) {
-      if ($format->name == 'Filtered HTML') {
-        $filtered = $format->format;
-      }
-      elseif ($format->name == 'Full HTML') {
-        $full = $format->format;
-      }
-    }
-
-    return array($filtered, $full);
+  function getFormatByName($name) {
+    drupal_static_reset('filter_formats');
+    $format =  db_query("SELECT format FROM {filter_format} WHERE name = :name", array(':name' => $name))->fetchField();
+    return filter_format_load($format);
   }
 
   /**
-   * Get filter by name.
-   *
-   * @param $name
-   *   Name of filter to find.
-   * @return
-   *   A filter object.
+   * Check if {cache_filter} table is empty.
    */
-  function getFilter($name) {
-    return db_query("SELECT * FROM {filter_format} WHERE name = :name", array(':name' => $name))->fetchObject();
+  function assertFilterCacheEmpty() {
+    $result = db_query_range('SELECT 1 FROM {cache_filter}', 0, 1)->fetchField();
+    $this->assertFalse($result, t('Filter cache cleared.'));
   }
 }
 
@@ -675,11 +653,11 @@
     $f = _filter_htmlcorrector('test <!--this is a comment-->');
     $this->assertEqual($f, 'test <!--this is a comment-->', t('HTML corrector -- Do not touch HTML comments.'));
 
-    $f = _filter_htmlcorrector('test <!-- comment <p>another 
-    <strong>multiple</strong> line 
+    $f = _filter_htmlcorrector('test <!-- comment <p>another
+    <strong>multiple</strong> line
     comment</p> -->');
-    $this->assertEqual($f, 'test <!-- comment <p>another 
-    <strong>multiple</strong> line 
+    $this->assertEqual($f, 'test <!-- comment <p>another
+    <strong>multiple</strong> line
     comment</p> -->', t('HTML corrector -- Do not touch HTML comments.'));
 
     $f = _filter_htmlcorrector('test <!-- comment <p>another comment</p> -->');
Index: modules/filter/filter.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v
retrieving revision 1.289
diff -u -r1.289 filter.module
--- modules/filter/filter.module	12 Sep 2009 06:09:45 -0000	1.289
+++ modules/filter/filter.module	13 Sep 2009 14:23:01 -0000
@@ -172,6 +172,7 @@
   }
   $format->roles = $roles;
   $format->name = trim($format->name);
+  $format->cache = _filter_format_allowcache($format);
 
   // Add a new text format.
   if (empty($format->format)) {
@@ -475,16 +476,47 @@
 function filter_resolve_format($format) {
   return $format == FILTER_FORMAT_DEFAULT ? variable_get('filter_default_format', 1) : $format;
 }
+
 /**
  * Check if text in a certain text format is allowed to be cached.
+ *
+ * This function can be used when filtering text, to check if the result of the
+ * filtering process can be cached. The given text format allow cache depending
+ * on the filters enabled.
+ *
+ * @param $format
+ *   The format ID.
+ * @return
+ *   TRUE if the given format allow cache, FALSE otherwise.
  */
 function filter_format_allowcache($format) {
-  static $cache = array();
   $format = filter_resolve_format($format);
-  if (!isset($cache[$format])) {
-    $cache[$format] = db_query('SELECT cache FROM {filter_format} WHERE format = :format', array(':format' => $format))->fetchField();
+  $format = filter_format_load($format);
+  return !empty($format->cache);
+}
+
+/**
+ * Helper function to determie if text in a given text format can be cached.
+ * 
+ * Text in a given text format is allowed to be cached if all the enabled
+ * filters in the format allow cache.
+ *
+ * @param $format
+ *   The format object to check.
+ * @return
+ *   TRUE if all the filters enabled in the given format allow cache, FALSE
+ *   otherwise.
+ */
+function _filter_format_allowcache($format) {
+  $filter_info = filter_get_filters();
+  $enabled_filters = array_keys(array_filter($format->filters));
+  foreach ($enabled_filters as $name) {
+    // By default, 'cache' is TRUE for all filters unless specified otherwise.
+    if (isset($filter_info[$name]['cache']) && !$filter_info[$name]['cache']) {
+      return FALSE; 
+    }
   }
-  return $cache[$format];
+  return TRUE;
 }
 
 /**
