import unittest


class remove_empty_tags_tests(unittest.TestCase):
    def _remove(self, value, extra_tags=[]):
        from ploneintranet.htmllaundry.utils import remove_empty_tags

        import lxml.etree

        fragment = lxml.etree.fromstring(value)
        fragment = remove_empty_tags(fragment, extra_tags)
        return lxml.etree.tostring(fragment, encoding=str)

    def testRemoveEmptyParagraphElement(self):
        self.assertEqual(self._remove("<div><p/></div>"), "<div/>")

    def testRemoveEmptyParagraph(self):
        self.assertEqual(self._remove("<div><p></p></div>"), "<div/>")

    def testRemoveParagraphWithWhitespace(self):
        self.assertEqual(self._remove("<div><p>  </p></div>"), "<div/>")

    def testRemoveParagraphWithUnicodeWhitespace(self):
        self.assertEqual(self._remove("<div><p> \xa0 </p></div>"), "<div/>")

    def testKeepEmptyImageElement(self):
        self.assertEqual(
            self._remove('<div><img src="image"/></div>'),
            '<div><img src="image"/></div>',
        )

    def testCollapseBreaks(self):
        self.assertEqual(
            self._remove("<body><p>one<br/><br/>two</p></body>"),
            "<body><p>one<br/>two</p></body>",
        )

    def testNestedData(self):
        self.assertEqual(
            self._remove("<div><h3><bad/></h3><p>Test</p></div>"),
            "<div><p>Test</p></div>",
        )

    def testKeepElementsWithTail(self):
        self.assertEqual(
            self._remove("<body>One<br/> two<br/> three</body>"),
            "<body>One<br/> two<br/> three</body>",
        )

    def testTrailingBreak(self):
        self.assertEqual(self._remove("<div>Test <br/></div>"), "<div>Test </div>")

    def testLeadingBreak(self):
        self.assertEqual(self._remove("<div><br/>Test</div>"), "<div>Test</div>")

    def testDoNotRemoveEmptyAnchorElement(self):
        # Should not remove empty <a> tag because it's used as an anchor:
        self.assertEqual(
            self._remove('<p><a id="anchor"></a></p>'), '<p><a id="anchor"/></p>'
        )
        self.assertEqual(
            self._remove('<p><a name="anchor" /></p>'), '<p><a name="anchor"/></p>'
        )
        self.assertEqual(
            self._remove('<p><a href="blah" id="anchor"/></p>'),
            '<p><a href="blah" id="anchor"/></p>',
        )
        self.assertEqual(
            self._remove('<p><a href="blah" name="anchor"/></p>'),
            '<p><a href="blah" name="anchor"/></p>',
        )

        # Should not remove <a> tag because it's non-empty:
        self.assertEqual(
            self._remove('<p><a href="blah" name="anchor">Link</a></p>'),
            '<p><a href="blah" name="anchor">Link</a></p>',
        )
        self.assertEqual(
            self._remove('<p><a name="anchor">Link</a></p>'),
            '<p><a name="anchor">Link</a></p>',
        )
        self.assertEqual(
            self._remove('<p><a href="anchor">Link</a></p>'),
            '<p><a href="anchor">Link</a></p>',
        )

        # Should remove because it's an useless empty tag.
        self.assertEqual(
            self._remove('<p><a href="blah"/>Content</p>'), "<p>Content</p>"
        )
        self.assertEqual(
            self._remove('<p><a href="blah"></a>Content</p>'), "<p>Content</p>"
        )

    def testExtraAllowedEmptyTags(self):
        self.assertEqual(
            self._remove("<table><tr><td>Test</td><td></td></tr></table>", ["td"]),
            "<table><tr><td>Test</td><td/></tr></table>",
        )


class ForceLinkTargetTests(unittest.TestCase):
    def force_link_target(self, value, target="_blank"):
        from ploneintranet.htmllaundry.cleaners import LaundryCleaner

        import lxml.etree

        fragment = lxml.etree.fromstring(value)
        cleaner = LaundryCleaner()
        cleaner.force_link_target(fragment, target)
        return lxml.etree.tostring(fragment, encoding=str)

    def testNoAnchor(self):
        self.assertEqual(self.force_link_target("<div><p/></div>"), "<div><p/></div>")

    def testAddTarget(self):
        self.assertEqual(
            self.force_link_target(
                '<div><a href="http://example.com"/></div>', "_blank"
            ),
            '<div><a href="http://example.com" target="_blank"/></div>',
        )

    def testRemoveTarget(self):
        self.assertEqual(
            self.force_link_target(
                '<div><a target="_blank" href="http://example.com"/></div>', None
            ),
            '<div><a href="http://example.com"/></div>',
        )


class strip_outer_breaks_tests(unittest.TestCase):
    def _strip(self, value):
        from ploneintranet.htmllaundry.utils import strip_outer_breaks

        import lxml.etree

        fragment = lxml.etree.fromstring(value)
        strip_outer_breaks(fragment)
        return lxml.etree.tostring(fragment, encoding=str)

    def testNoBreak(self):
        self.assertEqual(
            self._strip("<body>Dummy text</body>"), "<body>Dummy text</body>"
        )

    def testTrailingBreak(self):
        self.assertEqual(
            self._strip("<body>Dummy text<br/></body>"), "<body>Dummy text</body>"
        )

    def testLeadingBreak(self):
        self.assertEqual(
            self._strip("<body><br/>Dummy text</body>"), "<body>Dummy text</body>"
        )

    def testBreakAfterElement(self):
        self.assertEqual(
            self._strip("<body><p>Dummy</p><br/>text</body>"),
            "<body><p>Dummy</p>text</body>",
        )
