from functools import partial

from nose.tools import eq_

from bleach import clean


clean = partial(clean, tags=['p'], attributes=['style'])


def test_allowed_css():
    tests = (
        ('font-family: Arial; color: red; float: left; '
         'background-color: red;', 'color: red;', ['color']),
        ('border: 1px solid blue; color: red; float: left;', 'color: red;',
         ['color']),
        ('border: 1px solid blue; color: red; float: left;',
         'color: red; float: left;', ['color', 'float']),
        ('color: red; float: left; padding: 1em;', 'color: red; float: left;',
         ['color', 'float']),
        ('color: red; float: left; padding: 1em;', 'color: red;', ['color']),
        ('cursor: -moz-grab;', 'cursor: -moz-grab;', ['cursor']),
        ('color: hsl(30,100%,50%);', 'color: hsl(30,100%,50%);', ['color']),
        ('color: rgba(255,0,0,0.4);', 'color: rgba(255,0,0,0.4);', ['color']),
        ("text-overflow: ',' ellipsis;", "text-overflow: ',' ellipsis;",
         ['text-overflow']),
        ('text-overflow: "," ellipsis;', 'text-overflow: "," ellipsis;',
         ['text-overflow']),
        ('font-family: "Arial";', 'font-family: "Arial";', ['font-family']),
    )

    p_single = '<p style="{0!s}">bar</p>'
    p_double = "<p style='{0!s}'>bar</p>"

    def check(i, o, s):
        if '"' in i:
            eq_(p_double.format(o), clean(p_double.format(i), styles=s))
        else:
            eq_(p_single.format(o), clean(p_single.format(i), styles=s))

    for i, o, s in tests:
        yield check, i, o, s


def test_valid_css():
    """The sanitizer should fix missing CSS values."""
    styles = ['color', 'float']
    eq_('<p style="float: left;">foo</p>',
        clean('<p style="float: left; color: ">foo</p>', styles=styles))
    eq_('<p style="">foo</p>',
        clean('<p style="color: float: left;">foo</p>', styles=styles))


def test_style_hang():
    """The sanitizer should not hang on any inline styles"""
    # TODO: Neaten this up. It's copypasta from MDN/Kuma to repro the bug
    style = ("""margin-top: 0px; margin-right: 0px; margin-bottom: 1.286em; """
             """margin-left: 0px; padding-top: 15px; padding-right: 15px; """
             """padding-bottom: 15px; padding-left: 15px; border-top-width: """
             """1px; border-right-width: 1px; border-bottom-width: 1px; """
             """border-left-width: 1px; border-top-style: dotted; """
             """border-right-style: dotted; border-bottom-style: dotted; """
             """border-left-style: dotted; border-top-color: rgb(203, 200, """
             """185); border-right-color: rgb(203, 200, 185); """
             """border-bottom-color: rgb(203, 200, 185); border-left-color: """
             """rgb(203, 200, 185); background-image: initial; """
             """background-attachment: initial; background-origin: initial; """
             """background-clip: initial; background-color: """
             """rgb(246, 246, 242); overflow-x: auto; overflow-y: auto; """
             """font: normal normal normal 100%/normal 'Courier New', """
             """'Andale Mono', monospace; background-position: initial """
             """initial; background-repeat: initial initial;""")
    html = '<p style="{0!s}">Hello world</p>'.format(style)
    styles = [
        'border', 'float', 'overflow', 'min-height', 'vertical-align',
        'white-space',
        'margin', 'margin-left', 'margin-top', 'margin-bottom', 'margin-right',
        'padding', 'padding-left', 'padding-top', 'padding-bottom',
        'padding-right',
        'background',
        'background-color',
        'font', 'font-size', 'font-weight', 'text-align', 'text-transform',
    ]

    expected = ("""<p style="margin-top: 0px; margin-right: 0px; """
                """margin-bottom: 1.286em; margin-left: 0px; padding-top: """
                """15px; padding-right: 15px; padding-bottom: 15px; """
                """padding-left: 15px; background-color: """
                """rgb(246, 246, 242); font: normal normal normal """
                """100%/normal 'Courier New', 'Andale Mono', monospace;">"""
                """Hello world</p>""")

    result = clean(html, styles=styles)
    eq_(expected, result)
