installConfig(['system', 'filter', 'filter_test']); } /** * Tests that the filter order is respected. */ public function testCheckMarkupFilterOrder() { // Create crazy HTML format. $crazy_format = FilterFormat::create([ 'format' => 'crazy', 'name' => 'Crazy', 'weight' => 1, 'filters' => [ 'filter_html_escape' => [ 'weight' => 10, 'status' => 1, ], 'filter_html' => [ 'weight' => -10, 'status' => 1, 'settings' => [ 'allowed_html' => '
', ], ], ], ]); $crazy_format->save(); $text = "
Llamas are
$actual_filtered_textExpected:
$expected_filtered_text"); $this->assertEqual( $actual_filtered_text, $expected_filtered_text, 'Expected filter result.' ); $actual_filtered_text_without_html_generators = check_markup($text, 'filtered_html', '', [FilterInterface::TYPE_MARKUP_LANGUAGE]); $this->verbose("Actual:
$actual_filtered_text_without_html_generatorsExpected:
$expected_filter_text_without_html_generators"); $this->assertEqual( $actual_filtered_text_without_html_generators, $expected_filter_text_without_html_generators, 'Expected filter result when skipping FilterInterface::TYPE_MARKUP_LANGUAGE filters.' ); // Related to @see FilterSecurityTest.php/testSkipSecurityFilters(), but // this check focuses on the ability to filter multiple filter types at once. // Drupal core only ships with these two types of filters, so this is the // most extensive test possible. $actual_filtered_text_without_html_generators = check_markup($text, 'filtered_html', '', [FilterInterface::TYPE_HTML_RESTRICTOR, FilterInterface::TYPE_MARKUP_LANGUAGE]); $this->verbose("Actual:
$actual_filtered_text_without_html_generatorsExpected:
$expected_filter_text_without_html_generators"); $this->assertEqual( $actual_filtered_text_without_html_generators, $expected_filter_text_without_html_generators, 'Expected filter result when skipping FilterInterface::TYPE_MARKUP_LANGUAGE filters, even when trying to disable filters of the FilterInterface::TYPE_HTML_RESTRICTOR type.' ); } /** * Tests the following functions for a variety of formats: * - \Drupal\filter\Entity\FilterFormatInterface::getHtmlRestrictions() * - \Drupal\filter\Entity\FilterFormatInterface::getFilterTypes() */ public function testFilterFormatAPI() { // Test on filtered_html. $filtered_html_format = FilterFormat::load('filtered_html'); $this->assertIdentical( $filtered_html_format->getHtmlRestrictions(), [ 'allowed' => [ 'p' => FALSE, 'br' => FALSE, 'strong' => FALSE, 'a' => ['href' => TRUE, 'hreflang' => TRUE], '*' => ['style' => FALSE, 'on*' => FALSE, 'lang' => TRUE, 'dir' => ['ltr' => TRUE, 'rtl' => TRUE]], ], ], 'FilterFormatInterface::getHtmlRestrictions() works as expected for the filtered_html format.' ); $this->assertIdentical( $filtered_html_format->getFilterTypes(), [FilterInterface::TYPE_HTML_RESTRICTOR, FilterInterface::TYPE_MARKUP_LANGUAGE], 'FilterFormatInterface::getFilterTypes() works as expected for the filtered_html format.' ); // Test on full_html. $full_html_format = FilterFormat::load('full_html'); $this->assertIdentical( $full_html_format->getHtmlRestrictions(), // Every tag is allowed. FALSE, 'FilterFormatInterface::getHtmlRestrictions() works as expected for the full_html format.' ); $this->assertIdentical( $full_html_format->getFilterTypes(), [], 'FilterFormatInterface::getFilterTypes() works as expected for the full_html format.' ); // Test on stupid_filtered_html, where nothing is allowed. $stupid_filtered_html_format = FilterFormat::create([ 'format' => 'stupid_filtered_html', 'name' => 'Stupid Filtered HTML', 'filters' => [ 'filter_html' => [ 'status' => 1, 'settings' => [ // Nothing is allowed. 'allowed_html' => '', ], ], ], ]); $stupid_filtered_html_format->save(); $this->assertIdentical( $stupid_filtered_html_format->getHtmlRestrictions(), // No tag is allowed. ['allowed' => []], 'FilterFormatInterface::getHtmlRestrictions() works as expected for the stupid_filtered_html format.' ); $this->assertIdentical( $stupid_filtered_html_format->getFilterTypes(), [FilterInterface::TYPE_HTML_RESTRICTOR], 'FilterFormatInterface::getFilterTypes() works as expected for the stupid_filtered_html format.' ); // Test on very_restricted_html, where there's two different filters of the // FilterInterface::TYPE_HTML_RESTRICTOR type, each restricting in different ways. $very_restricted_html_format = FilterFormat::create([ 'format' => 'very_restricted_html', 'name' => 'Very Restricted HTML', 'filters' => [ 'filter_html' => [ 'status' => 1, 'settings' => [ 'allowed_html' => '
Hello, world! Hello, world! This is a dynamic llama. ',
],
],
],
]);
$crazy_format->save();
// Use config to directly load the configuration and check that only enabled
// or customized plugins are saved to configuration.
$filters = $this->config('filter.format.crazy')->get('filters');
$this->assertEqual(['filter_html_escape', 'filter_html'], array_keys($filters));
// Disable a plugin to ensure that disabled plugins with custom settings are
// stored in configuration.
$crazy_format->setFilterConfig('filter_html_escape', ['status' => FALSE]);
$crazy_format->save();
$filters = $this->config('filter.format.crazy')->get('filters');
$this->assertEqual(['filter_html_escape', 'filter_html'], array_keys($filters));
// Set the settings as per default to ensure that disable plugins in this
// state are not stored in configuration.
$crazy_format->setFilterConfig('filter_html_escape', ['weight' => -10]);
$crazy_format->save();
$filters = $this->config('filter.format.crazy')->get('filters');
$this->assertEqual(['filter_html'], array_keys($filters));
}
/**
* Checks if an expected violation exists in the given violations.
*
* @param \Symfony\Component\Validator\ConstraintViolationListInterface $violations
* The violations to assert.
* @param mixed $invalid_value
* The expected invalid value.
*/
public function assertFilterFormatViolation(ConstraintViolationListInterface $violations, $invalid_value) {
$filter_format_violation_found = FALSE;
foreach ($violations as $violation) {
if ($violation->getRoot() instanceof FilterFormatDataType && $violation->getInvalidValue() === $invalid_value) {
$filter_format_violation_found = TRUE;
break;
}
}
$this->assertTrue($filter_format_violation_found, format_string('Validation violation for invalid value "%invalid_value" found', ['%invalid_value' => $invalid_value]));
}
/**
* Tests that filter format dependency removal works.
*
* Ensure that modules providing filter plugins are required when the plugin
* is in use, and that only disabled plugins are removed from format
* configuration entities rather than the configuration entities being
* deleted.
*
* @see \Drupal\filter\Entity\FilterFormat::onDependencyRemoval()
* @see filter_system_info_alter()
*/
public function testDependencyRemoval() {
$this->installSchema('user', ['users_data']);
$filter_format = FilterFormat::load('filtered_html');
// Disable the filter_test_restrict_tags_and_attributes filter plugin but
// have custom configuration so that the filter plugin is still configured
// in filtered_html the filter format.
$filter_config = [
'weight' => 20,
'status' => 0,
];
$filter_format->setFilterConfig('filter_test_restrict_tags_and_attributes', $filter_config)->save();
// Use the get method to match the assert after the module has been
// uninstalled.
$filters = $filter_format->get('filters');
$this->assertTrue(isset($filters['filter_test_restrict_tags_and_attributes']), 'The filter plugin filter_test_restrict_tags_and_attributes is configured by the filtered_html filter format.');
drupal_static_reset('filter_formats');
\Drupal::entityManager()->getStorage('filter_format')->resetCache();
$module_data = \Drupal::service('extension.list.module')->reset()->getList();
$this->assertFalse(isset($module_data['filter_test']->info['required']), 'The filter_test module is required.');
// Verify that a dependency exists on the module that provides the filter
// plugin since it has configuration for the disabled plugin.
$this->assertEqual(['module' => ['filter_test']], $filter_format->getDependencies());
// Uninstall the module.
\Drupal::service('module_installer')->uninstall(['filter_test']);
// Verify the filter format still exists but the dependency and filter is
// gone.
\Drupal::entityManager()->getStorage('filter_format')->resetCache();
$filter_format = FilterFormat::load('filtered_html');
$this->assertEqual([], $filter_format->getDependencies());
// Use the get method since the FilterFormat::filters() method only returns
// existing plugins.
$filters = $filter_format->get('filters');
$this->assertFalse(isset($filters['filter_test_restrict_tags_and_attributes']), 'The filter plugin filter_test_restrict_tags_and_attributes is not configured by the filtered_html filter format.');
}
}
',
],
],
'filter_test_restrict_tags_and_attributes' => [
'status' => 1,
'settings' => [
'restrictions' => [
'allowed' => [
'p' => TRUE,
'br' => FALSE,
'a' => ['href' => TRUE],
'em' => TRUE,
],
],
],
],
],
]);
$very_restricted_html_format->save();
$this->assertIdentical(
$very_restricted_html_format->getHtmlRestrictions(),
[
'allowed' => [
'p' => FALSE,
'br' => FALSE,
'a' => ['href' => TRUE],
'*' => ['style' => FALSE, 'on*' => FALSE, 'lang' => TRUE, 'dir' => ['ltr' => TRUE, 'rtl' => TRUE]],
],
],
'FilterFormatInterface::getHtmlRestrictions() works as expected for the very_restricted_html format.'
);
$this->assertIdentical(
$very_restricted_html_format->getFilterTypes(),
[FilterInterface::TYPE_HTML_RESTRICTOR],
'FilterFormatInterface::getFilterTypes() works as expected for the very_restricted_html format.'
);
// Test on nonsensical_restricted_html, where the allowed attribute values
// contain asterisks, which do not have any meaning, but which we also
// cannot prevent because configuration can be modified outside of forms.
$nonsensical_restricted_html = FilterFormat::create([
'format' => 'nonsensical_restricted_html',
'name' => 'Nonsensical Restricted HTML',
'filters' => [
'filter_html' => [
'status' => 1,
'settings' => [
'allowed_html' => '