Project

General

Profile

Revision 02c4a1e7

ID02c4a1e751b5e5251c5a542fd5b668951a15fa26
Parent 04cd2200
Child d3bc1ee3

Added by Francois POIROTTE almost 7 years ago

[#1543] Compatibilité TG 2.3.x

Change-Id: I9171224d261ccbc2d9a1b3d3c9107f10742bdd54
Refs: #1543

View differences:

app_cfg.py
20 20
from vigilo.turbogears import VigiloAppConfig
21 21

  
22 22
import vigiboard
23
from vigiboard.lib import app_globals, helpers # pylint: disable-msg=W0611
23
from vigiboard.lib import app_globals # pylint: disable-msg=W0611
24 24
# W0611: Unused import: imports nécessaires pour le fonctionnement
25 25

  
26 26

  
deployment/who.ini
15 15
rememberer_name = auth_tkt
16 16
post_login_url = /post_login
17 17
post_logout_url = /post_logout
18
encoding = utf-8
18
charset = utf-8
19 19

  
20 20
[general]
21 21
request_classifier = vigilo.turbogears.repoze.classifier:vigilo_classifier
......
39 39
[mdproviders]
40 40
plugins =
41 41
    vigilo.turbogears.repoze.plugins.mduser:plugin
42
    vigilo.turbogears.repoze.plugins.mdgroups:plugin
setup.cfg
1 1
[nosetests]
2
with-pylons=test.ini
3 2
cover-package=vigiboard
4 3
tests=vigiboard/tests
5 4

  
setup.py
43 43
    url='http://www.projet-vigilo.org/',
44 44
    install_requires=[
45 45
        "vigilo-turbogears",
46
        "tw.forms",
47 46
    ],
48 47

  
49 48
    packages=find_packages(exclude=['ez_setup']),
......
72 71
        'paste.app_factory': [
73 72
            'main = vigiboard.config.middleware:make_app',
74 73
        ],
75
        'paste.app_install': [
76
            'main = pylons.util:PylonsInstaller',
77
        ],
78 74
        'vigilo.models': [
79 75
            'populate_db = vigiboard.websetup:populate_db',
80 76
        ],
vigiboard/controllers/feeds.py
7 7
import logging
8 8
from tg import expose, response
9 9
from datetime import datetime
10
from tg.controllers import CUSTOM_CONTENT_TYPE
11 10

  
12 11
from vigilo.turbogears.controllers import BaseController
13 12

  
......
18 17
class FeedsController(BaseController):
19 18
    # pylint: disable-msg=R0201,W0613
20 19

  
21
    @expose('atom.xml', content_type=CUSTOM_CONTENT_TYPE)
20
    @expose('atom.xml')
22 21
    def atom(self, token, username):
23 22
        """
24 23
        """
vigiboard/controllers/plugins/date.py
9 9
"""
10 10
from datetime import datetime, timedelta
11 11
import tw.forms as twf
12
from pylons.i18n import ugettext as _, lazy_ugettext as l_
12
from tg.i18n import ugettext as _, lazy_ugettext as l_
13 13

  
14 14
from vigilo.models import tables
15 15

  
vigiboard/controllers/plugins/details.py
11 11

  
12 12
import urllib
13 13
from tg import config, url, request
14
from pylons.i18n import lazy_ugettext as l_
14
from tg.i18n import lazy_ugettext as l_
15 15
import tw.forms as twf
16 16
from sqlalchemy.sql.expression import null as expr_null, union_all
17 17
from sqlalchemy import func
18 18

  
19
from repoze.what.predicates import has_permission, in_group
19
from tg.predicates import has_permission, in_group
20 20
from vigilo.turbogears.helpers import get_current_user
21 21

  
22 22
from vigilo.models.session import DBSession
......
83 83
            items = DBSession.query(
84 84
                    Map.idmap,
85 85
                    Map.title,
86
                    func.lower(Map.title),
87 86
                ).distinct(
88 87
                ).join(
89 88
                    (MAP_GROUP_TABLE, MAP_GROUP_TABLE.c.idmap == Map.idmap),
90
                    (MapGroup, MapGroup.idgroup == MAP_GROUP_TABLE.c.idgroup),
91 89
                    (MapNodeHost, MapNodeHost.idmap == Map.idmap),
92 90
                ).order_by(func.lower(Map.title).asc()
93 91
                ).filter(MapNodeHost.idhost == event.idhost)
......
95 93
            if not is_manager:
96 94
                mapgroups = get_current_user().mapgroups(only_direct=True)
97 95
                # pylint: disable-msg=E1103
98
                items = items.filter(MapGroup.idgroup.in_(mapgroups))
96
                items = items.filter(MAP_GROUP_TABLE.c.idgroup.in_(mapgroups))
99 97

  
100 98
            # La valeur -1 supprime la limite.
101 99
            if max_maps > 0:
......
202 200
            return
203 201

  
204 202
        states = []
205
        for value in search.get('state'):
203
        for value in search.get('state', []):
206 204
            try:
207 205
                states.append(int(value))
208 206
            except (ValueError, TypeError):
209 207
                try:
210 208
                    states.append(StateName.statename_to_value(value))
211 209
                except:
212
                    # On ignore silencieusement un critère de recherche erroné.
210
                    # On ignore silencieusement un critère de recherche erroné
213 211
                    pass
214 212

  
215 213
        if states:
vigiboard/controllers/plugins/groups.py
9 9
à l'événement corrélé.
10 10
"""
11 11
import tw.forms as twf
12
from pylons.i18n import lazy_ugettext as l_
12
from tg.i18n import lazy_ugettext as l_
13 13

  
14 14
from vigiboard.controllers.plugins import VigiboardRequestPlugin, INNER
15 15
from vigilo.models.session import DBSession
vigiboard/controllers/plugins/hls.py
9 9
"""
10 10

  
11 11
import tw.forms as twf
12
from pylons.i18n import lazy_ugettext as l_
12
from tg.i18n import lazy_ugettext as l_
13 13

  
14 14
from vigiboard.controllers.plugins import VigiboardRequestPlugin, INNER
15 15
from vigilo.models.session import DBSession
......
28 28
            twf.TextField(
29 29
                'hls',
30 30
                label_text=l_('High-Level Service'),
31
                validator=twf.validators.String(if_missing=None),
31
                validator=twf.validators.UnicodeString(if_missing=None),
32 32
            )
33 33
        ]
34 34

  
vigiboard/controllers/plugins/hostname.py
8 8
sur lequel porte l'événement corrélé.
9 9
"""
10 10
import tw.forms as twf
11
from pylons.i18n import lazy_ugettext as l_
11
from tg.i18n import lazy_ugettext as l_
12 12

  
13 13
from vigilo.models.functions import sql_escape_like
14 14
from vigiboard.controllers.plugins import VigiboardRequestPlugin, ITEMS
vigiboard/controllers/plugins/map.py
8 8
sur lequel porte l'événement corrélé.
9 9
"""
10 10
import tw.forms as twf
11
from pylons.i18n import lazy_ugettext as l_
11
from tg.i18n import lazy_ugettext as l_
12 12
from sqlalchemy.sql.expression import union_all
13 13
from sqlalchemy.orm import aliased
14 14

  
vigiboard/controllers/plugins/output.py
8 8
de la commande de test exécutée par Nagios sur cet hôte/service.
9 9
"""
10 10
import tw.forms as twf
11
from pylons.i18n import lazy_ugettext as l_
11
from tg.i18n import lazy_ugettext as l_
12 12

  
13 13
from vigilo.models.tables import Event
14 14
from vigilo.models.functions import sql_escape_like
......
21 21
            twf.TextField(
22 22
                'output',
23 23
                label_text=l_('Output'),
24
                validator=twf.validators.String(if_missing=None),
24
                validator=twf.validators.UnicodeString(if_missing=None),
25 25
            )
26 26
        ]
27 27

  
vigiboard/controllers/plugins/priority.py
8 8
ITIL de l'événement corrélé.
9 9
"""
10 10
import tw.forms as twf
11
from pylons.i18n import lazy_ugettext as l_
11
from tg.i18n import lazy_ugettext as l_
12 12

  
13 13
from vigilo.models.tables import CorrEvent, StateName
14 14
from vigiboard.controllers.plugins import VigiboardRequestPlugin, ITEMS
vigiboard/controllers/plugins/servicename.py
8 8
à l'origine de l'événement corrélé.
9 9
"""
10 10
import tw.forms as twf
11
from pylons.i18n import lazy_ugettext as l_
11
from tg.i18n import lazy_ugettext as l_
12 12

  
13 13
from vigilo.models.functions import sql_escape_like
14 14
from vigiboard.controllers.plugins import VigiboardRequestPlugin, ITEMS
......
24 24
            twf.TextField(
25 25
                'service',
26 26
                label_text=l_('Service'),
27
                validator=twf.validators.String(if_missing=None),
27
                validator=twf.validators.UnicodeString(if_missing=None),
28 28
            )
29 29
        ]
30 30

  
vigiboard/controllers/plugins/state.py
9 9
import urllib
10 10
import tg
11 11
import tw.forms as twf
12
from pylons.i18n import lazy_ugettext as l_
12
from tg.i18n import lazy_ugettext as l_
13 13

  
14 14
from vigilo.models.tables import CorrEvent, Event, StateName
15 15
from vigilo.models.session import DBSession
vigiboard/controllers/plugins/status.py
14 14
import urllib
15 15
import tg
16 16
import tw.forms as twf
17
from pylons.i18n import lazy_ugettext as l_
17
from tg.i18n import lazy_ugettext as l_
18 18

  
19 19
from vigilo.models.tables import CorrEvent, StateName
20 20
from vigilo.models.functions import sql_escape_like
......
47 47
            twf.TextField(
48 48
                'trouble_ticket',
49 49
                label_text=l_('Trouble Ticket'),
50
                validator=twf.validators.String(if_missing=None),
50
                validator=twf.validators.UnicodeString(if_missing=None),
51 51
            ),
52 52
            twf.SingleSelectField(
53 53
                'ack',
vigiboard/controllers/root.py
5 5

  
6 6
"""VigiBoard Controller"""
7 7

  
8
import gettext
9
import os.path
8 10
from datetime import datetime
9 11
from time import mktime
10 12

  
11 13
from pkg_resources import resource_filename, working_set
12 14

  
13 15
from tg.exceptions import HTTPNotFound
14
from tg.controllers import CUSTOM_CONTENT_TYPE
15 16
from tg import expose, validate, require, flash, url, \
16 17
    tmpl_context, request, response, config, session, redirect
17
from webhelpers import paginate
18
from tw.forms import validators
19
from pylons.i18n import ugettext as _, lazy_ugettext as l_, get_lang
18
from tg.support import paginate
19
from formencode import validators, schema
20
from tg.i18n import ugettext as _, lazy_ugettext as l_, get_lang
20 21
from sqlalchemy import asc
21 22
from sqlalchemy.sql import func
22 23
from sqlalchemy.orm import aliased
23 24
from sqlalchemy.sql.expression import or_
24
from repoze.what.predicates import Any, All, NotAuthorizedError, \
25
                                    has_permission, not_anonymous
26
from formencode import schema
25
from tg.predicates import Any, All, NotAuthorizedError, \
26
                            has_permission, not_anonymous
27 27

  
28 28
from vigilo.models.session import DBSession
29 29
from vigilo.models.tables import Event, EventHistory, CorrEvent, Host, \
......
67 67
    Le controller général de vigiboard
68 68
    """
69 69
    _tickets = None
70
    _use_index_fallback = True
70 71

  
71 72
    error = ErrorController()
72 73
    autocomplete = AutoCompleteController()
......
126 127
        )
127 128

  
128 129
        # Paramètres de tri
129
        sort = validators.String(if_missing=None)
130
        sort = validators.UnicodeString(if_missing='')
130 131
        order = validators.OneOf(['asc', 'desc'], if_missing='asc')
131 132

  
132
        # Nécessaire pour que les critères de recherche soient conservés.
133
        allow_extra_fields = True
134

  
135
        # 2ème validation, cette fois avec les champs
136
        # du formulaire de recherche.
133
        # Le fait de chaîner la validation avec le formulaire de recherche
134
        # permet de convertir les critères de recherche vers leur type.
137 135
        chained_validators = [create_search_form.validator]
138 136

  
137
        allow_extra_fields = True
138

  
139 139
    @validate(
140 140
        validators=IndexSchema(),
141 141
        error_handler = process_form_errors)
142
    @expose('events_table.html', content_type=CUSTOM_CONTENT_TYPE)
142
    @expose('events_table.html')
143 143
    @require(access_restriction)
144
    def index(self, page, sort=None, order=None, **search):
144
    def index(self, page=None, sort=None, order=None, **search):
145 145
        """
146 146
        Page d'accueil de Vigiboard. Elle affiche, suivant la page demandée
147 147
        (page 1 par defaut), la liste des événements, rangés par ordre de prise
......
181 181
            Event.idsupitem == aggregates.items.c.idsupitem))
182 182
        aggregates.add_order_by(asc(aggregates.items.c.hostname))
183 183

  
184
        # Certains arguments sont réservés dans routes.util.url_for().
185
        # On effectue les substitutions adéquates.
186
        # Par exemple: "host" devient "host_".
187
        reserved = ('host', 'anchor', 'protocol', 'qualified')
188
        for column in search.copy():
189
            if column in reserved:
190
                search[column + '_'] = search[column]
191
                del search[column]
192

  
193 184
        # On ne garde que les champs effectivement renseignés.
194 185
        for column in search.copy():
195 186
            if not search[column]:
......
260 251
        )
261 252

  
262 253

  
263
    @expose(content_type=CUSTOM_CONTENT_TYPE)
254
    @expose()
264 255
    def i18n(self):
265
        import gettext
266
        import pylons
267
        import os.path
268

  
269
        # Repris de pylons.i18n.translation:_get_translator.
270
        conf = pylons.config.current_conf()
256
        # Repris de tg.i18n:_get_translator.
257
        conf = config.current_conf()
271 258
        try:
272
            rootdir = conf['pylons.paths']['root']
259
            localedir = conf['localedir']
273 260
        except KeyError:
274
            rootdir = conf['pylons.paths'].get('root_path')
275
        localedir = os.path.join(rootdir, 'i18n')
261
            localedir = os.path.join(conf['paths']['root'], 'i18n')
276 262

  
277 263
        lang = get_lang()
278 264

  
279 265
        # Localise le fichier *.mo actuellement chargé
280 266
        # et génère le chemin jusqu'au *.js correspondant.
281
        filename = gettext.find(conf['pylons.package'], localedir,
267
        filename = gettext.find(conf['package'].__name__, localedir,
282 268
            languages=lang)
283 269
        js = filename[:-3] + '.js'
284 270

  
......
311 297
        error_handler = process_form_errors)
312 298
    @expose('raw_events_table.html')
313 299
    @require(access_restriction)
314
    def masked_events(self, idcorrevent, page):
300
    def masked_events(self, idcorrevent, page=1):
315 301
        """
316 302
        Affichage de la liste des événements bruts masqués d'un événement
317 303
        corrélé (événements agrégés dans l'événement corrélé).
......
397 383
        error_handler = process_form_errors)
398 384
    @expose('history_table.html')
399 385
    @require(access_restriction)
400
    def event(self, idevent, page):
386
    def event(self, idevent, page=1):
401 387
        """
402 388
        Affichage de l'historique d'un événement brut.
403 389
        Pour accéder à cette page, l'utilisateur doit être authentifié.
......
473 459
        error_handler = process_form_errors)
474 460
    @expose('events_table.html')
475 461
    @require(access_restriction)
476
    def item(self, page, host, service, sort=None, order=None):
462
    def item(self, page=1, host=None, service=None, sort=None, order=None):
477 463
        """
478 464
        Affichage de l'historique de l'ensemble des événements corrélés
479 465
        jamais ouverts sur l'hôte / service demandé.
vigiboard/controllers/silence.py
10 10

  
11 11
from tg import expose, validate, require, flash, tmpl_context, \
12 12
    request, config, redirect
13
from pylons.i18n import lazy_ugettext as l_, ugettext as _
14
#from tg.i18n import get_lang
15

  
16
#from tw.forms import CalendarDateTimePicker
17
from webhelpers import paginate
18
from tw.forms import validators
19

  
20
from vigilo.turbogears.helpers import get_current_user
21
from repoze.what.predicates import Any, All, in_group, \
13
from tg.i18n import lazy_ugettext as l_, ugettext as _
14
from tg.support import paginate
15
from tg.predicates import Any, All, in_group, \
22 16
                                    has_permission, not_anonymous
23
from formencode import schema
17
from formencode import validators, schema
24 18
from formencode.compound import All as All_
25 19
from formencode.foreach import ForEach
26

  
27 20
from sqlalchemy.exc import InvalidRequestError, IntegrityError
28 21
from sqlalchemy.sql.expression import asc, desc
29 22

  
23
from vigilo.turbogears.helpers import get_current_user
30 24
from vigilo.turbogears.controllers import BaseController
31 25
from vigilo.models.session import DBSession
32

  
33 26
from vigilo.models.tables import SupItem, Host, LowLevelService, \
34 27
                            HighLevelService, StateName, Silence, UserSupItem
35 28
from vigilo.models.tables.secondary_tables import SILENCE_STATE_TABLE
36

  
37 29
from vigilo.models.utils import group_concat
38 30

  
39 31
from vigiboard.lib import error_handler
vigiboard/controllers/vigiboardrequest.py
9 9
from time import mktime
10 10

  
11 11
from tg import config, tmpl_context, request, url
12
from pylons.i18n import ugettext as _
12
from tg.i18n import ugettext as _
13 13
from paste.deploy.converters import aslist
14 14

  
15 15
from sqlalchemy import not_, and_, asc, desc
vigiboard/lib/dateformat.py
8 8
from formencode.api import FancyValidator, Invalid
9 9
from datetime import datetime
10 10

  
11
from pylons.i18n import ugettext as _
11
from tg.i18n import ugettext as _, get_lang
12 12

  
13 13
def get_calendar_lang():
14
    from tg.i18n import get_lang
15 14
    import tg
16 15

  
17 16
    # TODO: Utiliser le champ "language" du modèle pour cet utilisateur ?
vigiboard/lib/helpers.py
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2007-2016 CS-SI
3
# License: GNU GPL v2 <http://www.gnu.org/licenses/gpl-2.0.html>
4

  
5
"""WebHelpers used in vigiboard."""
6

  
7
#from webhelpers import date, feedgenerator, html, number, misc, text
vigiboard/tests/functional/plugins/test_details_plugin_maps.py
12 12
from vigiboard.tests import TestController
13 13
from vigilo.models.session import DBSession
14 14
from vigilo.models.demo import functions
15
from vigilo.models.tables import Permission, CorrEvent, Host, LowLevelService
15
from vigilo.models import tables
16 16

  
17 17
class TestDetailsPluginMapsHostLimited(TestController):
18 18
    """
......
21 21
    """
22 22
    application_under_test = 'limited_maps'
23 23
    # Seules les 2 premières cartes doivent figurer.
24
    # La 1ère correspond à la limite, la 2 seconde permet
24
    # La 1ère correspond à la limite, la seconde permet
25 25
    # de détecter qu'il y avait plus de cartes que la limite.
26 26
    manager = [[1, 'M1'], [2, 'M2']]
27 27
    # L'utilisateur avec droits étendus voit
......
30 30
    # L'utilisateur avec droits restreints ne voit
31 31
    # qu'une seule carte : "M2".
32 32
    restricted = [[2, 'M2']]
33
    supitem_class = Host
33
    supitem_class = tables.Host
34 34

  
35 35
    def shortDescription(self, *args, **kwargs):
36 36
        """Description courte du test en cours d'exécution."""
......
43 43
        # On fait manuellement ce que l'initialisation de VigiMap ferait
44 44
        # (car on est dans les tests de VigiBoard, pas ceux de VigiMap).
45 45
        root = functions.add_mapgroup(u'Root')
46
        DBSession.add(Permission(permission_name=u'vigimap-access'))
46
        DBSession.add(tables.Permission(permission_name=u'vigimap-access'))
47 47

  
48 48
        print "Creation hote, service et cartes"
49 49
        host = functions.add_host(u'localhost éçà')
......
106 106
        print "Insertion evenement correle"
107 107
        timestamp = datetime.now()
108 108
        supitem = DBSession.query(self.supitem_class).one()
109
        if isinstance(supitem, Host):
109
        if isinstance(supitem, tables.Host):
110 110
            event = functions.add_event(supitem, u'DOWN', u'', timestamp)
111 111
        else: # Sinon, il s'agit d'un LowLevelService.
112 112
            event = functions.add_event(supitem, u'CRITICAL', u'', timestamp)
113 113
        functions.add_correvent([event], timestamp=timestamp)
114 114
        DBSession.flush()
115 115
        transaction.commit()
116
        correvent = DBSession.query(CorrEvent.idcorrevent).one()
116
        correvent = DBSession.query(tables.CorrEvent.idcorrevent).one()
117 117
        return correvent.idcorrevent
118 118

  
119 119
    def test_maps_links_anonymous(self):
......
217 217
    Idem que la classe mère mais teste un événement corrélé
218 218
    portant sur un service de l'hôte plutôt que sur l'hôte lui-même.
219 219
    """
220
    supitem_class = LowLevelService
220
    supitem_class = tables.LowLevelService
221 221

  
222 222
    def shortDescription(self, *args, **kwargs):
223 223
        """Description courte du test en cours d'exécution."""
......
232 232
    Idem que la classe mère mais teste un événement corrélé
233 233
    portant sur un service de l'hôte plutôt que sur l'hôte lui-même.
234 234
    """
235
    supitem_class = LowLevelService
235
    supitem_class = tables.LowLevelService
236 236

  
237 237
    def shortDescription(self, *args, **kwargs):
238 238
        """Description courte du test en cours d'exécution."""
......
247 247
    Idem que la classe mère mais teste un événement corrélé
248 248
    portant sur un service de l'hôte plutôt que sur l'hôte lui-même.
249 249
    """
250
    supitem_class = LowLevelService
250
    supitem_class = tables.LowLevelService
251 251

  
252 252
    def shortDescription(self, *args, **kwargs):
253 253
        """Description courte du test en cours d'exécution."""
vigiboard/tests/functional/test_correvents_table.py
101 101
        """
102 102
        Tableau des événements corrélés pour un service de bas niveau.
103 103
        """
104
        url = '/item/1/%s/%s' % ('group2_host', 'group2_service')
104
        url = '/item/1/group2_host/group2_service'
105 105

  
106 106
        # L'utilisateur n'est pas authentifié.
107 107
        response = self.app.get(url, status=401)
......
141 141
        """
142 142
        Tableau des événements corrélés pour un hôte.
143 143
        """
144
        url = '/item/1/%s/' % ('group2_host', )
144
        url = '/item/1/group2_host/'
145 145

  
146 146
        # L'utilisateur n'est pas authentifié.
147 147
        response = self.app.get(url, status=401)
vigiboard/tests/functional/test_search_form_misc.py
176 176
        from_date = from_date.strftime("%Y-%m-%d %I:%M:%S %p")
177 177
        to_date = datetime.now().strftime("%Y-%m-%d %I:%M:%S %p")
178 178

  
179
        # Démarrage du test
180
        rows = self.get_number_of_rows(from_date, to_date)
179
        # La recherche en utilisant une date de début supérieure
180
        # à la date actuelle doit générer une erreur/redirection.
181
        environ = {'REMOTE_USER': 'user'}
182
        resp = self.app.get(
183
            '/?from_date=%(from_date)s&to_date=%(to_date)s' % {
184
                'from_date': from_date,
185
                'to_date': to_date,
186
            },
187
            extra_environ=environ,
188
            status=302)
181 189

  
182
        # Aucun résultat.
183
        assert_equal(rows, 0)
190
        # Après redirection, le message d'erreur apparait dans la page.
191
        resp = resp.follow(extra_environ=environ)
192
        error = '<div id="flash"><div class="error">%s</div></div>' % \
193
            'Start date cannot be greater than current date'
194
        assert_true(error in resp.body)
184 195

  
185 196
    def test_future_end_date(self):
186 197
        """Contrôle des dates. Vérifie que date de fin < date courante."""
......
192 203
        to_date = datetime.now() + timedelta(seconds=60)
193 204
        to_date = to_date.strftime("%Y-%m-%d %I:%M:%S %p")
194 205

  
195
        # Démarrage du test
196
        rows = self.get_number_of_rows(from_date, to_date)
206
        # La recherche en utilisant une date de fin supérieure
207
        # à la date courante doit générer une erreur/redirection.
208
        environ = {'REMOTE_USER': 'user'}
209
        resp = self.app.get(
210
            '/?from_date=%(from_date)s&to_date=%(to_date)s' % {
211
                'from_date': from_date,
212
                'to_date': to_date,
213
            },
214
            extra_environ=environ,
215
            status=302)
197 216

  
198
        # Aucun résultat.
199
        assert_equal(rows, 0)
217
        # Après redirection, le message d'erreur apparait dans la page.
218
        resp = resp.follow(extra_environ=environ)
219
        error = '<div id="flash"><div class="error">%s</div></div>' % \
220
            'End date cannot be greater than current date'
221
        assert_true(error in resp.body)
200 222

  
201 223
    def test_dates_inconsistency(self):
202 224
        """Contrôle des dates. Vérifie date de début <= date de fin."""
......
208 230
        from_date = from_date.strftime("%Y-%m-%d %I:%M:%S %p")
209 231
        to_date = timestamp.strftime("%Y-%m-%d %I:%M:%S %p")
210 232

  
211
        # Démarrage du test
212
        rows = self.get_number_of_rows(from_date, to_date)
233
        # La recherche en utilisant une date de début supérieure
234
        # à la date de fin doit générer une erreur/redirection.
235
        environ = {'REMOTE_USER': 'user'}
236
        resp = self.app.get(
237
            '/?from_date=%(from_date)s&to_date=%(to_date)s' % {
238
                'from_date': from_date,
239
                'to_date': to_date,
240
            },
241
            extra_environ=environ,
242
            status=302)
243

  
244
        # Après redirection, le message d'erreur apparait dans la page.
245
        resp = resp.follow(extra_environ=environ)
246
        error = '<div id="flash"><div class="error">%s</div></div>' % \
247
            'Start date cannot be greater than end date'
248
        assert_true(error in resp.body)
213 249

  
214
        # Aucun résultat.
215
        assert_equal(rows, 0)
vigiboard/widgets/edit_event.py
5 5

  
6 6
"""Le formulaire d'édition d'un événement."""
7 7

  
8
from pylons.i18n import lazy_ugettext as l_
8
from tg.i18n import lazy_ugettext as l_
9 9
from tw.api import WidgetsList
10 10
from tw.forms import TableForm, SingleSelectField, TextField, \
11 11
                        HiddenField, Label
vigiboard/widgets/search_form.py
5 5

  
6 6
"""Le formulaire de recherche/filtrage."""
7 7

  
8
from pylons.i18n import lazy_ugettext as l_
8
from tg.i18n import lazy_ugettext as l_
9 9
import tw.forms as twf
10 10
import tg
11 11

  

Also available in: Unified diff