mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-03-11 17:18:44 +00:00
[1.7.0] Refactor HTMLModule unit tests
- AttrCollections does not barf when an inclusion is not present - HTMLDefinition configuration directives now use new syntax - Added %HTML.AllowedModules and %HTML.CoreModules for testing - Extend Harness so that it can accept a default configuration object member variable - Refactor modules to use Scaffolding, which defines some custom attributes that allows for the easy testing of attribute collections git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1082 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
parent
2945f6a930
commit
a470fc5621
@ -63,6 +63,7 @@ class HTMLPurifier_AttrCollections
|
||||
if (isset($seen[$merge[$i]])) continue;
|
||||
$seen[$merge[$i]] = true;
|
||||
// foreach attribute of the inclusion, copy it over
|
||||
if (!isset($this->info[$merge[$i]])) continue;
|
||||
foreach ($this->info[$merge[$i]] as $key => $value) {
|
||||
if (isset($attr[$key])) continue; // also catches more inclusions
|
||||
$attr[$key] = $value;
|
||||
|
@ -7,48 +7,63 @@ require_once 'HTMLPurifier/HTMLModuleManager.php';
|
||||
// outside of the HTML or Attr namespaces
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'HTML', 'BlockWrapper', 'p', 'string',
|
||||
'String name of element to wrap inline elements that are inside a block '.
|
||||
'context. This only occurs in the children of blockquote in strict mode. '.
|
||||
'Example: by default value, <code><blockquote>Foo</blockquote></code> '.
|
||||
'would become <code><blockquote><p>Foo</p></blockquote></code>. The '.
|
||||
'<code><p></code> tags can be replaced '.
|
||||
'with whatever you desire, as long as it is a block level element. '.
|
||||
'This directive has been available since 1.3.0.'
|
||||
);
|
||||
'HTML', 'BlockWrapper', 'p', 'string', '
|
||||
<p>
|
||||
String name of element to wrap inline elements that are inside a block
|
||||
context. This only occurs in the children of blockquote in strict mode.
|
||||
</p>
|
||||
<p>
|
||||
Example: by default value,
|
||||
<code><blockquote>Foo</blockquote></code> would become
|
||||
<code><blockquote><p>Foo</p></blockquote></code>.
|
||||
The <code><p></code> tags can be replaced with whatever you desire,
|
||||
as long as it is a block level element. This directive has been available
|
||||
since 1.3.0.
|
||||
</p>
|
||||
');
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'HTML', 'Parent', 'div', 'string',
|
||||
'String name of element that HTML fragment passed to library will be '.
|
||||
'inserted in. An interesting variation would be using span as the '.
|
||||
'parent element, meaning that only inline tags would be allowed. '.
|
||||
'This directive has been available since 1.3.0.'
|
||||
);
|
||||
'HTML', 'Parent', 'div', 'string', '
|
||||
<p>
|
||||
String name of element that HTML fragment passed to library will be
|
||||
inserted in. An interesting variation would be using span as the
|
||||
parent element, meaning that only inline tags would be allowed.
|
||||
This directive has been available since 1.3.0.
|
||||
</p>
|
||||
');
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'HTML', 'AllowedElements', null, 'lookup/null',
|
||||
'If HTML Purifier\'s tag set is unsatisfactory for your needs, you '.
|
||||
'can overload it with your own list of tags to allow. Note that this '.
|
||||
'method is subtractive: it does its job by taking away from HTML Purifier '.
|
||||
'usual feature set, so you cannot add a tag that HTML Purifier never '.
|
||||
'supported in the first place (like embed, form or head). If you change this, you '.
|
||||
'probably also want to change %HTML.AllowedAttributes. '.
|
||||
'<strong>Warning:</strong> If another directive conflicts with the '.
|
||||
'elements here, <em>that</em> directive will win and override. '.
|
||||
'This directive has been available since 1.3.0.'
|
||||
);
|
||||
'HTML', 'AllowedElements', null, 'lookup/null', '
|
||||
<p>
|
||||
If HTML Purifier\'s tag set is unsatisfactory for your needs, you
|
||||
can overload it with your own list of tags to allow. Note that this
|
||||
method is subtractive: it does its job by taking away from HTML Purifier
|
||||
usual feature set, so you cannot add a tag that HTML Purifier never
|
||||
supported in the first place (like embed, form or head). If you
|
||||
change this, you probably also want to change %HTML.AllowedAttributes.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Warning:</strong> If another directive conflicts with the
|
||||
elements here, <em>that</em> directive will win and override.
|
||||
This directive has been available since 1.3.0.
|
||||
</p>
|
||||
');
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'HTML', 'AllowedAttributes', null, 'lookup/null',
|
||||
'IF HTML Purifier\'s attribute set is unsatisfactory, overload it! '.
|
||||
'The syntax is \'tag.attr\' or \'*.attr\' for the global attributes '.
|
||||
'(style, id, class, dir, lang, xml:lang).'.
|
||||
'<strong>Warning:</strong> If another directive conflicts with the '.
|
||||
'elements here, <em>that</em> directive will win and override. For '.
|
||||
'example, %HTML.EnableAttrID will take precedence over *.id in this '.
|
||||
'directive. You must set that directive to true before you can use '.
|
||||
'IDs at all. This directive has been available since 1.3.0.'
|
||||
);
|
||||
'HTML', 'AllowedAttributes', null, 'lookup/null', '
|
||||
<p>
|
||||
If HTML Purifier\'s attribute set is unsatisfactory, overload it!
|
||||
The syntax is "tag.attr" or "*.attr" for the global attributes
|
||||
(style, id, class, dir, lang, xml:lang).
|
||||
</p>
|
||||
<p>
|
||||
<strong>Warning:</strong> If another directive conflicts with the
|
||||
elements here, <em>that</em> directive will win and override. For
|
||||
example, %HTML.EnableAttrID will take precedence over *.id in this
|
||||
directive. You must set that directive to true before you can use
|
||||
IDs at all. This directive has been available since 1.3.0.
|
||||
</p>
|
||||
');
|
||||
|
||||
/**
|
||||
* Definition of the purified HTML that describes allowed children,
|
||||
|
@ -53,6 +53,43 @@ HTMLPurifier_ConfigSchema::define(
|
||||
'will be used. This directive has been available since 1.7.0.'
|
||||
);
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'HTML', 'AllowedModules', null, 'lookup/null', '
|
||||
<p>
|
||||
A doctype comes with a set of usual modules to use. Without having
|
||||
to mucking about with the doctypes, you can quickly activate or
|
||||
disable these modules by specifying which modules you wish to allow
|
||||
with this directive. This is most useful for unit testing specific
|
||||
modules, although end users may find it useful for their own ends.
|
||||
</p>
|
||||
<p>
|
||||
If you specify a module that does not exist, the manager will silently
|
||||
fail to use it, so be careful! User-defined modules are not affected
|
||||
by this directive. Modules defined in %HTML.CoreModules are not
|
||||
affected by this directive. This directive has been available since 1.7.0.
|
||||
</p>
|
||||
');
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'HTML', 'CoreModules', array(
|
||||
'Structure' => true,
|
||||
'Text' => true,
|
||||
'Hypertext' => true,
|
||||
'List' => true,
|
||||
'NonXMLCommonAttributes' => true,
|
||||
'XMLCommonAttributes' => true,
|
||||
'CommonAttributes' => true
|
||||
), 'lookup', '
|
||||
<p>
|
||||
Certain modularized doctypes (XHTML, namely), have certain modules
|
||||
that must be included for the doctype to be an conforming document
|
||||
type: put those modules here. By default, XHTML\'s core modules
|
||||
are used. You can set this to a blank array to disable core module
|
||||
protection, but this is not recommended. This directive has been
|
||||
available since 1.7.0.
|
||||
</p>
|
||||
');
|
||||
|
||||
class HTMLPurifier_HTMLModuleManager
|
||||
{
|
||||
|
||||
@ -254,6 +291,17 @@ class HTMLPurifier_HTMLModuleManager
|
||||
$doctype = $this->doctypes->make($config);
|
||||
$modules = $doctype->modules;
|
||||
|
||||
// take out the default modules that aren't allowed
|
||||
$lookup = $config->get('HTML', 'AllowedModules');
|
||||
$special_cases = $config->get('HTML', 'CoreModules');
|
||||
|
||||
if (is_array($lookup)) {
|
||||
foreach ($modules as $k => $m) {
|
||||
if (isset($special_cases[$m])) continue;
|
||||
if (!isset($lookup[$m])) unset($modules[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
// merge in custom modules
|
||||
$modules = array_merge($modules, $this->userModules);
|
||||
|
||||
@ -291,7 +339,6 @@ class HTMLPurifier_HTMLModuleManager
|
||||
// the module in your custom doctype should be sufficient
|
||||
$this->modules
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,7 +70,7 @@ class HTMLPurifier_AttrCollectionsTest extends UnitTestCase
|
||||
$types = new HTMLPurifier_AttrTypesMock($this);
|
||||
$collections = new HTMLPurifier_AttrCollections($types, array());
|
||||
$collections->info = array(
|
||||
'Core' => array(0 => array('Inclusion'), 'attr-original' => 'Type'),
|
||||
'Core' => array(0 => array('Inclusion', 'Undefined'), 'attr-original' => 'Type'),
|
||||
'Inclusion' => array(0 => array('SubInclusion'), 'attr' => 'Type'),
|
||||
'SubInclusion' => array('attr2' => 'Type')
|
||||
);
|
||||
|
@ -7,21 +7,15 @@ class HTMLPurifier_HTMLModule_BdoTest extends HTMLPurifier_HTMLModuleHarness
|
||||
|
||||
function test() {
|
||||
|
||||
$this->setupScaffold('Bdo');
|
||||
|
||||
// max
|
||||
$this->assertResult(
|
||||
'<span>
|
||||
<bdo
|
||||
id="test-id"
|
||||
class="class-name"
|
||||
style="font-weight:bold;"
|
||||
title="Title of tag"
|
||||
lang="en"
|
||||
xml:lang="en"
|
||||
dir="rtl"
|
||||
>
|
||||
<bdo ac:core="yes" dir="rtl">
|
||||
#PCDATA <span>Inline</span>
|
||||
</bdo>
|
||||
</span>', true, array('Attr.EnableID' => true)
|
||||
</span>'
|
||||
);
|
||||
|
||||
// min
|
||||
|
@ -7,21 +7,23 @@ class HTMLPurifier_HTMLModule_EditTest extends HTMLPurifier_HTMLModuleHarness
|
||||
|
||||
function test() {
|
||||
|
||||
$this->setupScaffold('Edit');
|
||||
|
||||
// max
|
||||
$this->assertResult(
|
||||
'<span>
|
||||
<ins cite="http://www.example.com/">
|
||||
<ins cite="http://www.example.com/" ac:common="yes">
|
||||
#PCDATA <span></span>
|
||||
</ins>
|
||||
<del cite="http://www.example.com/">
|
||||
<del cite="http://www.example.com/" ac:common="yes">
|
||||
#PCDATA <span></span>
|
||||
</del>
|
||||
</span>
|
||||
<div>
|
||||
<ins cite="http://www.example.com/">
|
||||
<ins cite="http://www.example.com/" ac:common="yes">
|
||||
#PCDATA <div></div> <span></span>
|
||||
</ins>
|
||||
<del cite="http://www.example.com/">
|
||||
<del cite="http://www.example.com/" ac:common="yes">
|
||||
#PCDATA <div></div> <span></span>
|
||||
</del>
|
||||
</div>'
|
||||
|
@ -7,6 +7,11 @@ class HTMLPurifier_HTMLModule_HypertextTest extends HTMLPurifier_HTMLModuleHarne
|
||||
|
||||
function test() {
|
||||
|
||||
$this->setupScaffold('Hypertext', array(
|
||||
'Attr.AllowedRel' => 'nofollow',
|
||||
'Attr.AllowedRev' => 'index'
|
||||
));
|
||||
|
||||
// max
|
||||
$this->assertResult(
|
||||
'<span>
|
||||
@ -14,13 +19,11 @@ class HTMLPurifier_HTMLModule_HypertextTest extends HTMLPurifier_HTMLModuleHarne
|
||||
href="http://www.example.com/"
|
||||
rel="nofollow"
|
||||
rev="index"
|
||||
ac:common="true"
|
||||
>
|
||||
#PCDATA <span>Inline</span>
|
||||
</a>
|
||||
</span>', true, array(
|
||||
'Attr.AllowedRel' => 'nofollow',
|
||||
'Attr.AllowedRev' => 'index'
|
||||
)
|
||||
</span>', true
|
||||
);
|
||||
|
||||
// invalid children
|
||||
|
@ -7,6 +7,8 @@ class HTMLPurifier_HTMLModule_ImageTest extends HTMLPurifier_HTMLModuleHarness
|
||||
|
||||
function test() {
|
||||
|
||||
$this->setupScaffold('Image');
|
||||
|
||||
// max
|
||||
$this->assertResult(
|
||||
'<span>
|
||||
@ -16,6 +18,7 @@ class HTMLPurifier_HTMLModule_ImageTest extends HTMLPurifier_HTMLModuleHarness
|
||||
longdesc="example.description.txt"
|
||||
height="42"
|
||||
width="42"
|
||||
ac:common="yes"
|
||||
/>
|
||||
</span>'
|
||||
);
|
||||
|
@ -7,12 +7,14 @@ class HTMLPurifier_HTMLModule_LegacyTest extends HTMLPurifier_HTMLModuleHarness
|
||||
|
||||
function test() {
|
||||
|
||||
$this->setupScaffold('Legacy');
|
||||
|
||||
// max
|
||||
$this->assertResult(
|
||||
'<span>
|
||||
<u>Text<span></span></u>
|
||||
<s>Text<span></span></s>
|
||||
<strike>Text<span></span></strike>
|
||||
<u ac:common="yes">Text<span></span></u>
|
||||
<s ac:common="yes">Text<span></span></s>
|
||||
<strike ac:common="yes">Text<span></span></strike>
|
||||
</span>'
|
||||
);
|
||||
|
||||
|
@ -9,6 +9,27 @@ class HTMLPurifier_HTMLModuleHarness extends HTMLPurifier_StrategyHarness
|
||||
parent::setup();
|
||||
$this->obj = new HTMLPurifier_Strategy_Core();
|
||||
}
|
||||
|
||||
function setupScaffold($module, $config = array()) {
|
||||
|
||||
$this->config = HTMLPurifier_Config::create($config);
|
||||
$this->config->set('HTML', 'AllowedModules', $module);
|
||||
$def =& $this->config->getHTMLDefinition(true);
|
||||
$def->manager->addModule(new HTMLPurifier_HTMLModuleHarness_Scaffold());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Special module that defines scaffolding for easy unit testing
|
||||
*/
|
||||
class HTMLPurifier_HTMLModuleHarness_Scaffold extends HTMLPurifier_HTMLModule
|
||||
{
|
||||
var $name = 'Scaffold';
|
||||
var $attr_collections = array(
|
||||
'Common' => array('ac:common' => 'Text'),
|
||||
'Core' => array('ac:core' => 'Text')
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
@ -72,6 +72,34 @@ class HTMLPurifier_HTMLModuleManagerTest extends UnitTestCase
|
||||
|
||||
}
|
||||
|
||||
function testAllowedModules() {
|
||||
|
||||
$manager = new HTMLPurifier_HTMLModuleManager();
|
||||
$manager->doctypes->register(
|
||||
'Fantasy Inventory 1.0', true,
|
||||
array('Weapons', 'Magic')
|
||||
);
|
||||
|
||||
// register these modules so it doesn't blow up
|
||||
$weapons_module = new HTMLPurifier_HTMLModule();
|
||||
$weapons_module->name = 'Weapons';
|
||||
$manager->registerModule($weapons_module);
|
||||
|
||||
$magic_module = new HTMLPurifier_HTMLModule();
|
||||
$magic_module->name = 'Magic';
|
||||
$manager->registerModule($magic_module);
|
||||
|
||||
$config = HTMLPurifier_Config::create(array(
|
||||
'HTML.Doctype' => 'Fantasy Inventory 1.0',
|
||||
'HTML.AllowedModules' => 'Weapons'
|
||||
));
|
||||
$manager->setup($config);
|
||||
|
||||
$this->assertTrue( isset($manager->modules['Weapons']));
|
||||
$this->assertFalse(isset($manager->modules['Magic']));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -42,6 +42,11 @@ class HTMLPurifier_Harness extends UnitTestCase
|
||||
*/
|
||||
var $generator;
|
||||
|
||||
/**
|
||||
* Default config to fall back on if no config is available
|
||||
*/
|
||||
var $config;
|
||||
|
||||
function HTMLPurifier_Harness() {
|
||||
$this->lexer = new HTMLPurifier_Lexer_DirectLex();
|
||||
$this->generator = new HTMLPurifier_Generator();
|
||||
@ -52,22 +57,24 @@ class HTMLPurifier_Harness extends UnitTestCase
|
||||
* Asserts a specific result from a one parameter + config/context function
|
||||
* @param $input Input parameter
|
||||
* @param $expect Expectation
|
||||
* @param $config_array Configuration array in form of
|
||||
* Namespace.Directive => Value or an actual config
|
||||
* object.
|
||||
* @param $config Configuration array in form of Ns.Directive => Value.
|
||||
* Has no effect if $this->config is set.
|
||||
* @param $context_array Context array in form of Key => Value or an actual
|
||||
* context object.
|
||||
*/
|
||||
function assertResult($input, $expect = true,
|
||||
$config_array = array(), $context_array = array()
|
||||
$config_array = false, $context_array = array()
|
||||
) {
|
||||
|
||||
// setup config object
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
$config->loadArray($config_array);
|
||||
// setup config
|
||||
if ($this->config) {
|
||||
$config = HTMLPurifier_Config::create($this->config);
|
||||
} else {
|
||||
$config = HTMLPurifier_Config::create($config_array);
|
||||
}
|
||||
|
||||
// setup context object. Note that we are operating on a copy of it!
|
||||
// We will extend the test harness to allow you to do post-tests
|
||||
// When necessary, extend the test harness to allow post-tests
|
||||
// on the context object
|
||||
$context = new HTMLPurifier_Context();
|
||||
$context->loadArray($context_array);
|
||||
|
Loading…
x
Reference in New Issue
Block a user