""" A short series of tests to check a proposed custom autoescape feature.
"""

from django.test import TestCase
from django.template import Template, Context
from django.utils.safestring import mark_safe

def custom_escape_function(value):
    return value.upper()
custom_escape_function.autoescape_context = "upper"

def number_escape(value):
    return value.replace("55", "00")
number_escape.autoescape_context = "number"

def rtfescape(value):
    return value.replace('\\', '\\\\').replace('{','\\{').replace('}', '\\}')
rtfescape.autoescape_context = "rtf"

class CustomAutoEscape(TestCase):
    def test_safe_string(self):
        t = Template("{{ val|addslashes }}")
        context = {'val': mark_safe("Joe's string")}
        self.assertEqual(
            t.render(Context(context, autoescape=rtfescape)),
            u"Joe\\\\'s string"
        )

    def test_unsafe_string(self):
        t = Template("{{ val|addslashes }}")
        context = {'val': "Joe's string"}
        self.assertEqual(
            t.render(Context(context, autoescape=rtfescape)),
            u"Joe\\\\'s string"
        )

    def test_manual_slashes(self):
        t = Template("{{ val }}")
        context = {'val': "Joe\\'s string"}
        self.assertEqual(
            t.render(Context(context, autoescape=rtfescape)),
            u"Joe\\\\'s string"
        )

    def test_filter_context_same(self):
        t = Template("{% load custom %}{{ val|odd_letters }}")
        context = {'val': "abcDEFghi"}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u"BDFH"
        )
        
    def test_filter_context_safe(self):
        """ Data marked as safe for a safe function with the same AE context should not be escaped. """
        t = Template("{% load custom %}{{ val|odd_letters }}")
        context = {'val': mark_safe("abcDEFghi")}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u"bDFh"
        )
        
    def test_filter_context_diff(self):
        """ Checks that changes from a filter marked .is_safe are not safe 
            when the filter is from a different context. 
        """
        t = Template("{{ val|lower }}")
        context = {'val': mark_safe("ABCDEFGHI")}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u"ABCDEFGHI"
        )
        
    def test_filter_context_diff_safe(self):
        t = Template("{% load custom %}{{ val|lower|safe }}")
        context = {'val': mark_safe("ABCDEFGHI")}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u"abcdefghi"
        )

    def test_filter_join(self):
        """ Tests the changed join filter that handles escaping itself. """
        t = Template('{{ val|join:", " }}')
        context = {'val': ["ab", "cD", "EF", "gh", mark_safe("ij")]}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u"AB, CD, EF, GH, ij"
        )

    def test_filter_force_escape(self):
        t = Template('{{ val|force_escape }}')
        context = {'val': mark_safe("ab")}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u"AB"
        )

    def test_filter_linenumbers(self):
        t = Template('{{ val|linenumbers }}')
        context = {'val': "abcde\nfghi"}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u"1. ABCDE\n2. FGHI"
        )

    def test_filter_unordered_list(self):
        t = Template('{{ val|unordered_list }}')
        context = {'val': ["abcde","fghi"]}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u"\t<li>ABCDE</li>\n\t<li>FGHI</li>"
        )
        
    def test_filter_linebreaks(self):
        t = Template('{{ val|linebreaks }}')
        context = {'val': "abcde\n\nfghi\njklm"}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u"<p>ABCDE</p>\n\n<p>FGHI<br />JKLM</p>"
        )
        
    def test_filter_linebreaksbr(self):
        t = Template('{{ val|linebreaksbr }}')
        context = {'val': "abcde\n\nfghi\njklm"}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u"ABCDE<br /><br />FGHI<br />JKLM"
        )

    def test_filter_urlize(self):
        t = Template('{{ val|urlize }}')
        context = {'val': "a link to www.test.com la"}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u'A LINK TO <a href="HTTP://WWW.TEST.COM" rel="nofollow">WWW.TEST.COM</a> LA'
        )

    def test_filter_urlizetrunc(self):
        t = Template('{{ val|urlizetrunc:5 }}')
        context = {'val': "a link to www.test.com la"}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u'A LINK TO <a href="HTTP://WWW.TEST.COM" rel="nofollow">WW...</a> LA'
        )

    def test_filter_slugify(self):
        t = Template('{{ val|slugify }}')
        context = {'val': "my title string"}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u'MY-TITLE-STRING'
        )

    def test_filter_floatformat(self):
        t = Template('{{ val|floatformat:2 }}')
        context = {'val': 1559}
        self.assertEqual(
            t.render(Context(context, autoescape=number_escape)),
            u'1009.00'
        )

    def test_filter_cut(self):
        """ Checks that post cut data is escaped. """
        t = Template('{{ val|cut:"xyz" }}')
        # Two fives will be together after xyz is removed
        context = {'val': mark_safe("abcDE5xyz5Bc")}
        self.assertEqual(
            t.render(Context(context, autoescape=number_escape)),
            u'abcDE00Bc'
        )

    def test_filter_markup_textile(self):
        t = Template('{% load markup %}{{ val|textile }}')
        context = {'val': "abcDEF"}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u'ABCDEF'
        )

    def test_filter_markup_markdown(self):
        t = Template('{% load markup %}{{ val|markdown }}')
        context = {'val': "abcDEF"}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u'ABCDEF'
        )

    def test_filter_markup_restructuredtext(self):
        t = Template('{% load markup %}{{ val|restructuredtext }}')
        context = {'val': "abcDEF"}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u'ABCDEF'
        )

    def test_filter_mark_safe(self):
        """ Checks a filter that marks its input as safe. """
        t = Template('{% load custom %}{{ val|safe_lower }}')
        context = {'val': "abcDEF"}
        self.assertEqual(
            t.render(Context(context, autoescape=custom_escape_function)),
            u'abcdef'
        )
