1 | from yatl.helpers import TAG, XML, DIV |
---|
2 | import unittest |
---|
3 | |
---|
4 | |
---|
5 | class TestHelpers(unittest.TestCase): |
---|
6 | def test_all_tags(self): |
---|
7 | for x in TAG.__all_tags__: |
---|
8 | self.assertEqual(TAG[x]().xml(), "<%s></%s>" % |
---|
9 | (x, x) if not x[-1] == "/" else "<%s>" % x) |
---|
10 | |
---|
11 | def test_tags(self): |
---|
12 | DIV = TAG.div |
---|
13 | IMG = TAG['img/'] |
---|
14 | self.assertEqual(DIV().xml(), "<div></div>") |
---|
15 | self.assertEqual(IMG().xml(), "<img/>") |
---|
16 | self.assertEqual(DIV(_id="my_id").xml(), "<div id=\"my_id\"></div>") |
---|
17 | self.assertEqual(IMG(_src="crazy").xml(), "<img src=\"crazy\"/>") |
---|
18 | self.assertEqual( |
---|
19 | DIV(_class="my_class", _mytrueattr=True).xml(), |
---|
20 | "<div class=\"my_class\" mytrueattr=\"mytrueattr\"></div>") |
---|
21 | self.assertEqual( |
---|
22 | DIV(_id="my_id", _none=None, _false=False, without_underline="serius?").xml(), |
---|
23 | "<div id=\"my_id\"></div>") |
---|
24 | self.assertEqual( |
---|
25 | DIV("<b>xmlscapedthis</b>").xml(), "<div><b>xmlscapedthis</b></div>") |
---|
26 | self.assertEqual( |
---|
27 | DIV(XML("<b>don'txmlscapedthis</b>")).xml(), "<div><b>don'txmlscapedthis</b></div>") |
---|
28 | |
---|
29 | def test_invalid_atribute_name(self): |
---|
30 | i = [" ", "=", "'", '"', ">", "<", "/"] |
---|
31 | for x in i: |
---|
32 | DIV = TAG.div |
---|
33 | b = "_any%sthings" % x |
---|
34 | attr = {b: "invalid_atribute_name"} |
---|
35 | self.assertRaises(ValueError, DIV("any content", **attr).xml) |
---|
36 | |
---|
37 | def test_amend(self): |
---|
38 | div = DIV('hello', _class='myclass') |
---|
39 | div = div.amend('hello world', _id='myid') |
---|
40 | self.assertEqual( |
---|
41 | div.xml(), |
---|
42 | '<div class="myclass" id="myid">hello world</div>') |
---|
43 | |
---|
44 | def test_sanitize(self): |
---|
45 | permitted_tags=[ |
---|
46 | 'div', |
---|
47 | 'td', |
---|
48 | 'b', |
---|
49 | 'br/', |
---|
50 | 'strong', |
---|
51 | 'span', |
---|
52 | 'img/', |
---|
53 | 'a', |
---|
54 | ] |
---|
55 | allowed_attributes={ |
---|
56 | 'a': ['href', 'title'], |
---|
57 | 'img': ['src', 'alt'], |
---|
58 | 'blockquote': ['type'], |
---|
59 | 'td': ['colspan'], |
---|
60 | } |
---|
61 | # test permitted |
---|
62 | for x in permitted_tags: |
---|
63 | T = TAG[x] |
---|
64 | s_tag = T().xml() |
---|
65 | if x == "img/": # alt or src attribute is required. src has to have a valid href |
---|
66 | s_tag = T(_alt="empty").xml() |
---|
67 | self.assertEqual(XML(s_tag, sanitize=True, permitted_tags=['img/'], allowed_attributes={'img': ['src', 'alt']}).xml(), |
---|
68 | "<img alt=\"empty\"/>") |
---|
69 | s_tag = T(_src="/image.png").xml() |
---|
70 | self.assertEqual(XML(s_tag, sanitize=True, permitted_tags=['img/'], allowed_attributes={'img': ['src', 'alt']}).xml(), |
---|
71 | "<img src=\"/image.png\"/>") |
---|
72 | elif x == "a": # It has to have a valid href or title or not tag empty |
---|
73 | s_tag = T("this is a link", _href="http://web2py.com/").xml() |
---|
74 | self.assertEqual(XML(s_tag, sanitize=True, permitted_tags=['a'], allowed_attributes={'a': ['href', 'title']}).xml(), |
---|
75 | "<a href=\"http://web2py.com/\">this is a link</a>") |
---|
76 | s_tag = T("without href", _title="this is a link?").xml() |
---|
77 | self.assertEqual(XML(s_tag, sanitize=True, permitted_tags=['a'], allowed_attributes={'a': ['href', 'title']}).xml(), |
---|
78 | '<a title="this is a link?">without href</a>') |
---|
79 | s_tag = T(_title="empty_tag").xml() |
---|
80 | self.assertEqual(XML(s_tag, sanitize=True, permitted_tags=['a'], allowed_attributes={'a': ['href', 'title']}).xml(), |
---|
81 | '<a title="empty_tag"></a>') |
---|
82 | else: |
---|
83 | self.assertEqual(XML(s_tag, sanitize=True, permitted_tags=permitted_tags, allowed_attributes=allowed_attributes).xml(), "<%s></%s>" % |
---|
84 | (x, x) if not x[-1] == "/" else "<%s>" % x) |
---|
85 | |
---|
86 | # test tag out of list |
---|
87 | out_of_list = [ |
---|
88 | 'blockquote', 'i', 'li', 'ol', 'ul', 'p', 'cite', 'code', 'pre', |
---|
89 | 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', |
---|
90 | 'table', 'tbody', 'thead', 'tfoot', 'tr' |
---|
91 | 'strong'] |
---|
92 | for x in out_of_list: |
---|
93 | T = TAG[x] |
---|
94 | self.assertEqual(XML(T().xml(), sanitize=True, permitted_tags=permitted_tags, allowed_attributes=allowed_attributes).xml(), "<%s></%s>" % |
---|
95 | (x, x)) |
---|
96 | # test unusual tags |
---|
97 | for x in ["evil", "n0c1v3"]: |
---|
98 | T = TAG[x] |
---|
99 | self.assertEqual(XML(T().xml(), sanitize=True, permitted_tags=permitted_tags, allowed_attributes=allowed_attributes).xml(), "<%s></%s>" % |
---|
100 | (x, x)) |
---|
101 | # test allowed_attributes |
---|
102 | s_tag = TAG['td']("content_td", _colspan="2", _extra_attr="invalid").xml() |
---|
103 | self.assertEqual(XML(s_tag, sanitize=True, permitted_tags=['td'], allowed_attributes={'td': ['colspan']}).xml(), |
---|
104 | '<td colspan="2">content_td</td>') |
---|
105 | s_tag = TAG['a']("link", _href="http://web2py.com/", _title="my_title").xml() |
---|
106 | self.assertEqual(XML(s_tag, sanitize=True, permitted_tags=['a'], allowed_attributes={'a': ['href', 'title']}).xml(), |
---|
107 | '<a href="http://web2py.com/" title="my_title">link</a>') |
---|
108 | s_tag = TAG['img/'](_alt="empty", _src="/images/logo.png").xml() |
---|
109 | self.assertEqual(XML(s_tag, sanitize=True, permitted_tags=['img/'], allowed_attributes={'img': ['src', 'alt']}).xml(), |
---|
110 | '<img src="/images/logo.png" alt="empty"/>') |
---|
111 | s_tag = TAG['div']("content", _style="{backgrond-color: red;}").xml() |
---|
112 | self.assertEqual(XML(s_tag, sanitize=True, permitted_tags=['div'], allowed_attributes={'div': ['style']}).xml(), |
---|
113 | '<div style="{backgrond-color: red;}">content</div>') |
---|
114 | self.assertEqual(XML(TAG['a']("oh no!", _href="invalid_link").xml(), sanitize=True, permitted_tags=['a']).xml(), 'oh no!') |
---|
115 | self.assertEqual(XML(TAG['div']("", _onclick="evil()").xml(), sanitize=True, permitted_tags=['div']).xml(), '<div></div>') |
---|
116 | |
---|
117 | # valid inside invalid |
---|
118 | s_tag = TAG['evil'](TAG['div']('valid'), _style="{backgrond-color: red;}").xml() |
---|
119 | self.assertEqual(XML(s_tag, sanitize=True, permitted_tags=['div'], allowed_attributes={'div': ['style']}).xml(), |
---|
120 | '<evil><div>valid</div></evil>') |
---|
121 | self.assertEqual(XML(TAG['a'](TAG['img/'](_src="/index.html"), _class="teste").xml(), sanitize=True, permitted_tags=['a', 'img/']).xml(), '<img src="/index.html"/>') |
---|
122 | |
---|
123 | # tags deleted even allowed |
---|
124 | self.assertEqual(XML(TAG['img/']().xml(), sanitize=True, permitted_tags=['img']).xml(), "") |
---|
125 | self.assertEqual(XML(TAG['img/'](_src="invalid_url").xml(), sanitize=True, permitted_tags=['img']).xml(), "") |
---|
126 | self.assertEqual(XML(TAG['img/'](_class="teste").xml(), sanitize=True, permitted_tags=['img']).xml(), "") |
---|
127 | self.assertEqual(XML(TAG['a'](_href="invalid_link").xml(), sanitize=True, permitted_tags=['a']).xml(), "") |
---|
128 | |
---|
129 | |
---|
130 | if __name__ == '__main__': |
---|
131 | unittest.main() |
---|