Projet

Général

Profil

0003-add-a-template-module-copycatting-wcs.qommon.templat.patch

Paul Marillonnet, 09 mars 2020 11:40

Télécharger (6,76 ko)

Voir les différences:

Subject: [PATCH 3/4] add a template module, copycatting wcs.qommon.template
 (#37884)

 src/authentic2/utils/template.py |  56 +++++++++++++++
 tests/test_template.py           | 113 +++++++++++++++++++++++++++++++
 2 files changed, 169 insertions(+)
 create mode 100644 src/authentic2/utils/template.py
 create mode 100644 tests/test_template.py
src/authentic2/utils/template.py
1
# authentic2 - versatile identity manager
2
# Copyright (C) 2010-2020 Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17
from django.template import VariableDoesNotExist
18
from django.template import engines
19
from django.template import TemplateSyntaxError
20
from django.utils.encoding import force_str
21
from django.utils.translation import ugettext_lazy as _
22

  
23

  
24
class TemplateError(Exception):
25
    pass
26

  
27

  
28
class Template(object):
29
    def __init__(self, value, raises=False):
30
        self.value = value
31
        self.raises = raises
32

  
33
        try:
34
            self.template = engines['django'].from_string(value)
35
        except TemplateSyntaxError as e:
36
            if self.raises:
37
                raise TemplateError(_('template syntax error: %s') % e)
38

  
39
    def render(self, context={}):
40
        if not hasattr(self, 'template'):
41
            # oops, silent error during initialization, let's get outta here
42
            return force_str(self.value)
43
        try:
44
            rendered = self.template.render(context)
45
        except TemplateSyntaxError as e:
46
            if self.raises:
47
                raise TemplateError(_('template syntax error: %s') % e)
48
            return force_str(self.value)
49
        except VariableDoesNotExist as e:
50
            if self.raises:
51
                raise TemplateError(_('missing template variable: %s') % e)
52
            return force_str(self.value)
53
        return force_str(rendered)
54

  
55
    def null_render(self, context={}):
56
        return str(self.value)
tests/test_template.py
1
# authentic2 - versatile identity manager
2
# Copyright (C) 2010-2020 Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17
import pytest
18

  
19
from authentic2.utils.template import Template, TemplateError
20

  
21
pytestmark = pytest.mark.django_db
22

  
23

  
24
def test_render_template():
25
    # 1.1. test a simple conditional
26
    value = '{% if foo %}John{% else %}Jim{% endif %}'
27
    template = Template(value=value)
28

  
29
    context = {'foo': True}
30
    assert template.render(context=context) == 'John'
31

  
32
    context = {'foo': False}
33
    assert template.render(context=context) == 'Jim'
34

  
35
    context = {}
36
    assert template.render(context=context) == 'Jim'
37

  
38
    # 1.2. test comparison operators
39
    value = '{% if foo > bar %}Foo{% else %}Bar{% endif %}'
40
    template = Template(value=value)
41

  
42
    context = {'foo': 3, 'bar': 2}
43
    assert template.render(context=context) == 'Foo'
44

  
45
    context = {'foo': 3, 'bar': 9}
46
    assert template.render(context=context) == 'Bar'
47

  
48
    # 1.3. test set operator
49
    value = '{% if foo in bar %}Found{% else %}Missing{% endif %}'
50
    template = Template(value=value)
51
    context = {
52
        'foo': 'john',
53
        'bar': ['miles', 'john', 'red', 'paul', 'philly joe']
54
    }
55
    assert template.render(context=context) == 'Found'
56

  
57
    context['bar'] = ['miles', 'wayne', 'herbie', 'ron', 'tony']
58
    assert template.render(context=context) == 'Missing'
59

  
60
    # 2. test 'add' builtin filter
61
    tmpl1 = Template(value='{{ base|add:suffix }}')
62
    tmpl2 = Template(value='{{ prefix|add:base }}')
63
    context = {
64
        'prefix': 'Mister ',
65
        'base': 'Tony',
66
        'suffix': ' Jr.',
67
    }
68

  
69
    assert tmpl1.render(context=context) == 'Tony Jr.'
70
    assert tmpl2.render(context=context) == 'Mister Tony'
71

  
72
    # 3. test 'with' tag
73
    value = '{% with name=user.name age=user.age %}{{ name }}: {{ age }}{% endwith %}'
74
    template = Template(value=value)
75

  
76
    context = {'user': {'name': 'Robert', 'age': 39 }}
77
    assert template.render(context=context) == 'Robert: 39'
78

  
79
    # 4. test 'firstof' tag
80
    value = '{% firstof name surname nickname %}'
81
    template = Template(value=value)
82

  
83
    context = {'surname': 'Smith', 'nickname': 'Mitch'}
84
    assert template.render(context=context) == 'Smith'
85

  
86
    context.pop('surname')
87
    assert template.render(context=context) == 'Mitch'
88

  
89

  
90
def test_render_template_syntax_error():
91
    value = '{% if foo %}John{% else %}Jim{% endif %' # oops
92
    template = Template(value=value)
93

  
94
    context = {'foo': True}
95
    assert template.render(context=context) == value
96

  
97
    with pytest.raises(TemplateError) as raised:
98
        template = Template(value=value, raises=True)
99
        assert 'template syntax error' in raised
100

  
101

  
102
def test_render_template_missing_variable():
103
    value = '{{ foo|add:bar }}'
104
    template = Template(value=value)
105

  
106
    context = {'foo': True}
107
    assert template.render(context=context) == value
108

  
109
    # missing variable errors happen at render time with a particular context
110
    template = Template(value=value, raises=True)
111
    with pytest.raises(TemplateError) as raised:
112
        template.render(context=context)
113
        assert 'missing template variable' in raised
0
-