diff options
Diffstat (limited to 'lib/htmlpurifier/tests/HTMLPurifier/Injector')
7 files changed, 924 insertions, 0 deletions
diff --git a/lib/htmlpurifier/tests/HTMLPurifier/Injector/AutoParagraphTest.php b/lib/htmlpurifier/tests/HTMLPurifier/Injector/AutoParagraphTest.php new file mode 100644 index 000000000..e6abbd1ff --- /dev/null +++ b/lib/htmlpurifier/tests/HTMLPurifier/Injector/AutoParagraphTest.php @@ -0,0 +1,515 @@ +<?php + +class HTMLPurifier_Injector_AutoParagraphTest extends HTMLPurifier_InjectorHarness +{ + + function setup() { + parent::setup(); + $this->config->set('AutoFormat.AutoParagraph', true); + } + + function testSingleParagraph() { + $this->assertResult( + 'Foobar', + '<p>Foobar</p>' + ); + } + + function testSingleMultiLineParagraph() { + $this->assertResult( +'Par 1 +Par 1 still', +'<p>Par 1 +Par 1 still</p>' + ); + } + + function testTwoParagraphs() { + $this->assertResult( +'Par1 + +Par2', +"<p>Par1</p> + +<p>Par2</p>" + ); + } + + function testTwoParagraphsWithLotsOfSpace() { + $this->assertResult( +'Par1 + + + +Par2', +'<p>Par1</p> + +<p>Par2</p>' + ); + } + + function testTwoParagraphsWithInlineElements() { + $this->assertResult( +'<b>Par1</b> + +<i>Par2</i>', +'<p><b>Par1</b></p> + +<p><i>Par2</i></p>' + ); + } + + function testSingleParagraphThatLooksLikeTwo() { + $this->assertResult( +'<b>Par1 + +Par2</b>', +'<p><b>Par1 + +Par2</b></p>' + ); + } + + function testAddParagraphAdjacentToParagraph() { + $this->assertResult( + 'Par1<p>Par2</p>', +'<p>Par1</p> + +<p>Par2</p>' + ); + } + + function testParagraphUnclosedInlineElement() { + $this->assertResult( + '<b>Par1', + '<p><b>Par1</b></p>' + ); + } + + function testPreservePreTags() { + $this->assertResult( +'<pre>Par1 + +Par1</pre>' + ); + } + + function testIgnoreTrailingWhitespace() { + $this->assertResult( +'Par1 + + ', +'<p>Par1</p> + +' + ); + } + + function testDoNotParagraphBlockElements() { + $this->assertResult( +'Par1 + +<div>Par2</div> + +Par3', +'<p>Par1</p> + +<div>Par2</div> + +<p>Par3</p>' + ); + } + + function testParagraphTextAndInlineNodes() { + $this->assertResult( +'Par<b>1</b>', + '<p>Par<b>1</b></p>' + ); + } + + function testPreserveLeadingWhitespace() { + $this->assertResult( +' + +Par', +' + +<p>Par</p>' + ); + } + + function testPreserveSurroundingWhitespace() { + $this->assertResult( +' + +Par + +', +' + +<p>Par</p> + +' + ); + } + + function testParagraphInsideBlockNode() { + $this->assertResult( +'<div>Par1 + +Par2</div>', +'<div><p>Par1</p> + +<p>Par2</p></div>' + ); + } + + function testParagraphInlineNodeInsideBlockNode() { + $this->assertResult( +'<div><b>Par1</b> + +Par2</div>', +'<div><p><b>Par1</b></p> + +<p>Par2</p></div>' + ); + } + + function testNoParagraphWhenOnlyOneInsideBlockNode() { + $this->assertResult('<div>Par1</div>'); + } + + function testParagraphTwoInlineNodesInsideBlockNode() { + $this->assertResult( +'<div><b>Par1</b> + +<i>Par2</i></div>', +'<div><p><b>Par1</b></p> + +<p><i>Par2</i></p></div>' + ); + } + + function testPreserveInlineNodesInPreTag() { + $this->assertResult( +'<pre><b>Par1</b> + +<i>Par2</i></pre>' + ); + } + + function testSplitUpInternalsOfPTagInBlockNode() { + $this->assertResult( +'<div><p>Foo + +Bar</p></div>', +'<div><p>Foo</p> + +<p>Bar</p></div>' + ); + } + + function testSplitUpInlineNodesInPTagInBlockNode() { + $this->assertResult( +'<div><p><b>Foo</b> + +<i>Bar</i></p></div>', +'<div><p><b>Foo</b></p> + +<p><i>Bar</i></p></div>' + ); + } + + function testNoParagraphSingleInlineNodeInBlockNode() { + $this->assertResult( '<div><b>Foo</b></div>' ); + } + + function testParagraphInBlockquote() { + $this->assertResult( +'<blockquote>Par1 + +Par2</blockquote>', +'<blockquote><p>Par1</p> + +<p>Par2</p></blockquote>' + ); + } + + function testNoParagraphBetweenListItem() { + $this->assertResult( +'<ul><li>Foo</li> + +<li>Bar</li></ul>' + ); + } + + function testParagraphSingleElementWithSurroundingSpace() { + $this->assertResult( +'<div> + +Bar + +</div>', + '<div> + +<p>Bar</p> + +</div>' + ); + } + + function testIgnoreExtraSpaceWithLeadingInlineNode() { + $this->assertResult( +'<b>Par1</b>a + + + +Par2', +'<p><b>Par1</b>a</p> + +<p>Par2</p>' + ); + } + + function testAbsorbExtraEndingPTag() { + $this->assertResult( +'Par1 + +Par2</p>', +'<p>Par1</p> + +<p>Par2</p>' + ); + } + + function testAbsorbExtraEndingDivTag() { + $this->assertResult( +'Par1 + +Par2</div>', +'<p>Par1</p> + +<p>Par2</p>' + ); + } + + function testDoNotParagraphSingleSurroundingSpaceInBlockNode() { + $this->assertResult( +'<div> +Par1 +</div>' + ); + } + + function testBlockNodeTextDelimeterInBlockNode() { + $this->assertResult( +'<div>Par1 + +<div>Par2</div></div>', +'<div><p>Par1</p> + +<div>Par2</div></div>' + ); + } + + function testBlockNodeTextDelimeterWithoutDoublespaceInBlockNode() { + $this->assertResult( +'<div>Par1 +<div>Par2</div></div>' + ); + } + + function testBlockNodeTextDelimeterWithoutDoublespace() { + $this->assertResult( +'Par1 +<div>Par2</div>', +'<p>Par1 +</p> + +<div>Par2</div>' + ); + } + + function testTwoParagraphsOfTextAndInlineNode() { + $this->assertResult( +'Par1 + +<b>Par2</b>', +'<p>Par1</p> + +<p><b>Par2</b></p>' + ); + } + + function testLeadingInlineNodeParagraph() { + $this->assertResult( +'<img /> Foo', +'<p><img /> Foo</p>' + ); + } + + function testTrailingInlineNodeParagraph() { + $this->assertResult( +'<li>Foo <a>bar</a></li>' + ); + } + + function testTwoInlineNodeParagraph() { + $this->assertResult( +'<li><b>baz</b><a>bar</a></li>' + ); + } + + function testNoParagraphTrailingBlockNodeInBlockNode() { + $this->assertResult( +'<div><div>asdf</div><b>asdf</b></div>' + ); + } + + function testParagraphTrailingBlockNodeWithDoublespaceInBlockNode() { + $this->assertResult( +'<div><div>asdf</div> + +<b>asdf</b></div>', +'<div><div>asdf</div> + +<p><b>asdf</b></p></div>' + ); + } + + function testParagraphTwoInlineNodesAndWhitespaceNode() { + $this->assertResult( +'<b>One</b> <i>Two</i>', +'<p><b>One</b> <i>Two</i></p>' + ); + } + + function testNoParagraphWithInlineRootNode() { + $this->config->set('HTML.Parent', 'span'); + $this->assertResult( +'Par + +Par2' + ); + } + + function testInlineAndBlockTagInDivNoParagraph() { + $this->assertResult( + '<div><code>bar</code> mmm <pre>asdf</pre></div>' + ); + } + + function testInlineAndBlockTagInDivNeedingParagraph() { + $this->assertResult( +'<div><code>bar</code> mmm + +<pre>asdf</pre></div>', +'<div><p><code>bar</code> mmm</p> + +<pre>asdf</pre></div>' + ); + } + + function testTextInlineNodeTextThenDoubleNewlineNeedsParagraph() { + $this->assertResult( +'<div>asdf <code>bar</code> mmm + +<pre>asdf</pre></div>', +'<div><p>asdf <code>bar</code> mmm</p> + +<pre>asdf</pre></div>' + ); + } + + function testUpcomingTokenHasNewline() { + $this->assertResult( +'<div>Test<b>foo</b>bar<b>bing</b>bang + +boo</div>', +'<div><p>Test<b>foo</b>bar<b>bing</b>bang</p> + +<p>boo</p></div>' +); + } + + function testEmptyTokenAtEndOfDiv() { + $this->assertResult( +'<div><p>foo</p> +</div>', +'<div><p>foo</p> +</div>' +); + } + + function testEmptyDoubleLineTokenAtEndOfDiv() { + $this->assertResult( +'<div><p>foo</p> + +</div>', +'<div><p>foo</p> + +</div>' +); + } + + function testTextState11Root() { + $this->assertResult('<div></div> '); + } + + function testTextState11Element() { + $this->assertResult( +"<div><div></div> + +</div>"); + } + + function testTextStateLikeElementState111NoWhitespace() { + $this->assertResult('<div><p>P</p>Boo</div>', '<div><p>P</p>Boo</div>'); + } + + function testElementState111NoWhitespace() { + $this->assertResult('<div><p>P</p><b>Boo</b></div>', '<div><p>P</p><b>Boo</b></div>'); + } + + function testElementState133() { + $this->assertResult( +"<div><b>B</b><pre>Ba</pre> + +Bar</div>", +"<div><b>B</b><pre>Ba</pre> + +<p>Bar</p></div>" +); + } + + function testElementState22() { + $this->assertResult( + '<ul><li>foo</li></ul>' + ); + } + + function testElementState311() { + $this->assertResult( + '<p>Foo</p><b>Bar</b>', +'<p>Foo</p> + +<p><b>Bar</b></p>' + ); + } + + function testAutoClose() { + $this->assertResult( + '<p></p> +<hr />' + ); + } + + function testErrorNeeded() { + $this->config->set('HTML.Allowed', 'b'); + $this->expectError('Cannot enable AutoParagraph injector because p is not allowed'); + $this->assertResult('<b>foobar</b>'); + } + +} + +// vim: et sw=4 sts=4 diff --git a/lib/htmlpurifier/tests/HTMLPurifier/Injector/DisplayLinkURITest.php b/lib/htmlpurifier/tests/HTMLPurifier/Injector/DisplayLinkURITest.php new file mode 100644 index 000000000..1629d9bd1 --- /dev/null +++ b/lib/htmlpurifier/tests/HTMLPurifier/Injector/DisplayLinkURITest.php @@ -0,0 +1,33 @@ +<?php + +class HTMLPurifier_Injector_DisplayLinkURITest extends HTMLPurifier_InjectorHarness +{ + + function setup() { + parent::setup(); + $this->config->set('AutoFormat.DisplayLinkURI', true); + } + + function testBasicLink() { + $this->assertResult( + '<a href="http://malware.example.com">Don\'t go here!</a>', + '<a>Don\'t go here!</a> (http://malware.example.com)' + ); + } + + function testEmptyLink() { + $this->assertResult( + '<a>Don\'t go here!</a>', + '<a>Don\'t go here!</a>' + ); + } + function testEmptyText() { + $this->assertResult( + '<a href="http://malware.example.com"></a>', + '<a></a> (http://malware.example.com)' + ); + } + +} + +// vim: et sw=4 sts=4 diff --git a/lib/htmlpurifier/tests/HTMLPurifier/Injector/LinkifyTest.php b/lib/htmlpurifier/tests/HTMLPurifier/Injector/LinkifyTest.php new file mode 100644 index 000000000..1a1542d53 --- /dev/null +++ b/lib/htmlpurifier/tests/HTMLPurifier/Injector/LinkifyTest.php @@ -0,0 +1,50 @@ +<?php + +class HTMLPurifier_Injector_LinkifyTest extends HTMLPurifier_InjectorHarness +{ + + function setup() { + parent::setup(); + $this->config->set('AutoFormat.Linkify', true); + } + + function testLinkifyURLInRootNode() { + $this->assertResult( + 'http://example.com', + '<a href="http://example.com">http://example.com</a>' + ); + } + + function testLinkifyURLInInlineNode() { + $this->assertResult( + '<b>http://example.com</b>', + '<b><a href="http://example.com">http://example.com</a></b>' + ); + } + + function testBasicUsageCase() { + $this->assertResult( + 'This URL http://example.com is what you need', + 'This URL <a href="http://example.com">http://example.com</a> is what you need' + ); + } + + function testIgnoreURLInATag() { + $this->assertResult( + '<a>http://example.com/</a>' + ); + } + + function testNeeded() { + $this->config->set('HTML.Allowed', 'b'); + $this->expectError('Cannot enable Linkify injector because a is not allowed'); + $this->assertResult('http://example.com/'); + } + + function testExcludes() { + $this->assertResult('<a><span>http://example.com</span></a>'); + } + +} + +// vim: et sw=4 sts=4 diff --git a/lib/htmlpurifier/tests/HTMLPurifier/Injector/PurifierLinkifyTest.php b/lib/htmlpurifier/tests/HTMLPurifier/Injector/PurifierLinkifyTest.php new file mode 100644 index 000000000..774b234ad --- /dev/null +++ b/lib/htmlpurifier/tests/HTMLPurifier/Injector/PurifierLinkifyTest.php @@ -0,0 +1,59 @@ +<?php + +class HTMLPurifier_Injector_PurifierLinkifyTest extends HTMLPurifier_InjectorHarness +{ + + function setup() { + parent::setup(); + $this->config->set('AutoFormat.PurifierLinkify', true); + $this->config->set('AutoFormat.PurifierLinkify.DocURL', '#%s'); + } + + function testNoTriggerCharacer() { + $this->assertResult('Foobar'); + } + + function testTriggerCharacterInIrrelevantContext() { + $this->assertResult('20% off!'); + } + + function testPreserveNamespace() { + $this->assertResult('%Core namespace (not recognized)'); + } + + function testLinkifyBasic() { + $this->assertResult( + '%Namespace.Directive', + '<a href="#Namespace.Directive">%Namespace.Directive</a>' + ); + } + + function testLinkifyWithAdjacentTextNodes() { + $this->assertResult( + 'This %Namespace.Directive thing', + 'This <a href="#Namespace.Directive">%Namespace.Directive</a> thing' + ); + } + + function testLinkifyInBlock() { + $this->assertResult( + '<div>This %Namespace.Directive thing</div>', + '<div>This <a href="#Namespace.Directive">%Namespace.Directive</a> thing</div>' + ); + } + + function testPreserveInATag() { + $this->assertResult( + '<a>%Namespace.Directive</a>' + ); + } + + function testNeeded() { + $this->config->set('HTML.Allowed', 'b'); + $this->expectError('Cannot enable PurifierLinkify injector because a is not allowed'); + $this->assertResult('%Namespace.Directive'); + } + +} + +// vim: et sw=4 sts=4 diff --git a/lib/htmlpurifier/tests/HTMLPurifier/Injector/RemoveEmptyTest.php b/lib/htmlpurifier/tests/HTMLPurifier/Injector/RemoveEmptyTest.php new file mode 100644 index 000000000..34dbc9515 --- /dev/null +++ b/lib/htmlpurifier/tests/HTMLPurifier/Injector/RemoveEmptyTest.php @@ -0,0 +1,80 @@ +<?php + +class HTMLPurifier_Injector_RemoveEmptyTest extends HTMLPurifier_InjectorHarness +{ + + public function setup() { + parent::setup(); + $this->config->set('AutoFormat.RemoveEmpty', true); + } + + function testPreserve() { + $this->assertResult('<b>asdf</b>'); + } + + function testRemove() { + $this->assertResult('<b></b>', ''); + } + + function testRemoveWithSpace() { + $this->assertResult('<b> </b>', ''); + } + + function testRemoveWithAttr() { + $this->assertResult('<b class="asdf"></b>', ''); + } + + function testRemoveIdAndName() { + $this->assertResult('<a id="asdf" name="asdf"></a>', ''); + } + + function testPreserveColgroup() { + $this->assertResult('<colgroup></colgroup>'); + } + + function testPreserveId() { + $this->config->set('Attr.EnableID', true); + $this->assertResult('<a id="asdf"></a>'); + } + + function testPreserveName() { + $this->config->set('Attr.EnableID', true); + $this->assertResult('<a name="asdf"></a>'); + } + + function testRemoveNested() { + $this->assertResult('<b><i></i></b>', ''); + } + + function testRemoveNested2() { + $this->assertResult('<b><i><u></u></i></b>', ''); + } + + function testRemoveNested3() { + $this->assertResult('<b> <i> <u> </u> </i> </b>', ''); + } + + function testRemoveNbsp() { + $this->config->set('AutoFormat.RemoveEmpty.RemoveNbsp', true); + $this->assertResult('<b> </b>', ''); + } + + function testRemoveNbspMix() { + $this->config->set('AutoFormat.RemoveEmpty.RemoveNbsp', true); + $this->assertResult('<b> </b>', ''); + } + + function testDontRemoveNbsp() { + $this->config->set('AutoFormat.RemoveEmpty.RemoveNbsp', true); + $this->assertResult('<td> </b>', "<td>\xC2\xA0</td>"); + } + + function testRemoveNbspExceptionsSpecial() { + $this->config->set('AutoFormat.RemoveEmpty.RemoveNbsp', true); + $this->config->set('AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions', 'b'); + $this->assertResult('<b> </b>', "<b>\xC2\xA0</b>"); + } + +} + +// vim: et sw=4 sts=4 diff --git a/lib/htmlpurifier/tests/HTMLPurifier/Injector/RemoveSpansWithoutAttributesTest.php b/lib/htmlpurifier/tests/HTMLPurifier/Injector/RemoveSpansWithoutAttributesTest.php new file mode 100755 index 000000000..704c1cd7b --- /dev/null +++ b/lib/htmlpurifier/tests/HTMLPurifier/Injector/RemoveSpansWithoutAttributesTest.php @@ -0,0 +1,99 @@ +<?php + +class HTMLPurifier_Injector_RemoveSpansWithoutAttributesTest extends HTMLPurifier_InjectorHarness +{ + function setup() { + parent::setup(); + $this->config->set('HTML.Allowed', 'span[class],div,p,strong,em'); + $this->config->set('AutoFormat.RemoveSpansWithoutAttributes', true); + } + + function testSingleSpan() { + $this->assertResult( + '<span>foo</span>', + 'foo' + ); + } + + function testSingleSpanWithAttributes() { + $this->assertResult( + '<span class="bar">foo</span>', + '<span class="bar">foo</span>' + ); + } + + function testSingleNestedSpan() { + $this->assertResult( + '<p><span>foo</span></p>', + '<p>foo</p>' + ); + } + + function testSingleNestedSpanWithAttributes() { + $this->assertResult( + '<p><span class="bar">foo</span></p>', + '<p><span class="bar">foo</span></p>' + ); + } + + + function testSpanWithChildren() { + $this->assertResult( + '<span>foo <strong>bar</strong> <em>baz</em></span>', + 'foo <strong>bar</strong> <em>baz</em>' + ); + } + + function testSpanWithSiblings() { + $this->assertResult( + '<p>before <span>inside</span> <strong>after</strong></p>', + '<p>before inside <strong>after</strong></p>' + ); + } + + function testNestedSpanWithSiblingsAndChildren() { + $this->assertResult( + '<p>a <span>b <em>c</em> d</span> e</p>', + '<p>a b <em>c</em> d e</p>' + ); + } + + function testNestedSpansWithoutAttributes() { + $this->assertResult( + '<span>one<span>two<span>three</span></span></span>', + 'onetwothree' + ); + } + + function testDeeplyNestedSpan() { + $this->assertResult( + '<div><div><div><span class="a">a <span>b</span> c</span></div></div></div>', + '<div><div><div><span class="a">a b c</span></div></div></div>' + ); + } + + function testSpanWithInvalidAttributes() { + $this->assertResult( + '<p><span snorkel buzzer="emu">foo</span></p>', + '<p>foo</p>' + ); + } + + function testNestedAlternateSpans() { + $this->assertResult( +'<span>a <span class="x">b <span>c <span class="y">d <span>e <span class="z">f +</span></span></span></span></span></span>', +'a <span class="x">b c <span class="y">d e <span class="z">f +</span></span></span>' + ); + } + + function testSpanWithSomeInvalidAttributes() { + $this->assertResult( + '<p><span buzzer="emu" class="bar">foo</span></p>', + '<p><span class="bar">foo</span></p>' + ); + } +} + +// vim: et sw=4 sts=4 diff --git a/lib/htmlpurifier/tests/HTMLPurifier/Injector/SafeObjectTest.php b/lib/htmlpurifier/tests/HTMLPurifier/Injector/SafeObjectTest.php new file mode 100644 index 000000000..59e0493c3 --- /dev/null +++ b/lib/htmlpurifier/tests/HTMLPurifier/Injector/SafeObjectTest.php @@ -0,0 +1,88 @@ +<?php + +/** + * This test is kinda weird, because it doesn't test the full safe object + * functionality, just a small section of it. Or maybe it's actually the right + * way. + */ +class HTMLPurifier_Injector_SafeObjectTest extends HTMLPurifier_InjectorHarness +{ + + function setup() { + parent::setup(); + // there is no AutoFormat.SafeObject directive + $this->config->set('AutoFormat.Custom', array(new HTMLPurifier_Injector_SafeObject())); + $this->config->set('HTML.Trusted', true); + } + + function testPreserve() { + $this->assertResult( + '<b>asdf</b>' + ); + } + + function testRemoveStrayParam() { + $this->assertResult( + '<param />', + '' + ); + } + + function testEditObjectParam() { + $this->assertResult( + '<object></object>', + '<object><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /></object>' + ); + } + + function testIgnoreStrayParam() { + $this->assertResult( + '<object><param /></object>', + '<object><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /></object>' + ); + } + + function testIgnoreDuplicates() { + $this->assertResult( + '<object><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /></object>' + ); + } + + function testIgnoreBogusData() { + $this->assertResult( + '<object><param name="allowScriptAccess" value="always" /><param name="allowNetworking" value="always" /></object>', + '<object><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /></object>' + ); + } + + function testIgnoreInvalidData() { + $this->assertResult( + '<object><param name="foo" value="bar" /></object>', + '<object><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /></object>' + ); + } + + function testKeepValidData() { + $this->assertResult( + '<object><param name="movie" value="bar" /></object>', + '<object data="bar"><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /><param name="movie" value="bar" /></object>' + ); + } + + function testNested() { + $this->assertResult( + '<object><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /><object></object></object>', + '<object><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /><object><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /></object></object>' + ); + } + + function testNotActuallyNested() { + $this->assertResult( + '<object><p><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /></p></object>', + '<object><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /><p></p></object>' + ); + } + +} + +// vim: et sw=4 sts=4 |