source: main/waeup.sirp/trunk/src/waeup/sirp/widgets/tests/test_phonewidget.py @ 7354

Last change on this file since 7354 was 7354, checked in by uli, 13 years ago

Update tests.

File size: 15.9 KB
Line 
1##
2## test_phonewidget.py
3## Login : <uli@pu.smp.net>
4## Started on  Sun Dec 11 15:42:40 2011 Uli Fouquet
5## $Id$
6##
7## Copyright (C) 2011 Uli Fouquet
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22"""
23Tests for PhoneWidget.
24
25Tests in here are an extended reformulation of the tests done in
26z3.widget as doctests for the usphone widget.
27"""
28import unittest
29from zope import schema
30# XXX: could we possibly get rid of zope.app.testing?
31from zope.app.testing.setup import placefulSetUp, placefulTearDown
32from zope.component import provideAdapter
33from zope.formlib.exception import WidgetInputErrorView
34from zope.formlib.interfaces import (
35    WidgetInputError, IInputWidget, IBrowserWidget, IWidgetInputError,
36    IWidgetInputErrorView)
37from zope.formlib.textwidgets import TextWidget
38from zope.interface import verify, Interface, implements
39from zope.publisher.browser import TestRequest
40from zope.publisher.interfaces.browser import IDefaultBrowserLayer
41from zope.schema.interfaces import ITextLine
42from waeup.sirp.widgets.phonewidget import PhoneWidget
43
44# Dummy content
45class ISampleContent(Interface):
46    foo = schema.TextLine(
47        title = u'Phone',
48        description = u'Phone number',
49        required = True)
50
51class SampleContent:
52    implements(ISampleContent)
53
54class PhoneWidgetTests(unittest.TestCase):
55    # Tests for phone widget
56
57    def setUp(self):
58        placefulSetUp()
59
60        # register TextLine views (so that subwidgets can be rendered)
61        provideAdapter(
62            TextWidget, (ITextLine, IDefaultBrowserLayer), IInputWidget)
63        # errors in forms
64        provideAdapter(
65            WidgetInputErrorView, (IWidgetInputError, IDefaultBrowserLayer),
66            IWidgetInputErrorView)
67
68        # setup some sample content to bind to (only neccessary for
69        # some of the tests)
70        self.content = SampleContent()
71        self.field = ISampleContent['foo']
72        self.field = self.field.bind(self.content)
73
74        # create an empty request. We need one to create a widget
75        self.request = TestRequest()
76        self.widget = PhoneWidget(self.field, self.request)
77        return
78
79    def tearDown(self):
80        placefulTearDown()
81        return
82
83    def test_ifaces(self):
84        # make sure we fullfill interface contracts
85        verify.verifyClass(IBrowserWidget, PhoneWidget)
86        verify.verifyClass(IInputWidget, PhoneWidget)
87        verify.verifyObject(IBrowserWidget, self.widget)
88        verify.verifyObject(IInputWidget, self.widget)
89        return
90
91    def test_attribs_set(self):
92        # make sure the public attributes are set correctly
93        self.assertEqual(self.widget.name, 'field.foo')
94        self.assertEqual(self.widget.label, u'Phone')
95        self.assertEqual(self.widget.hint, u'Phone number')
96        self.assertEqual(self.widget.visible, True)
97        self.assertEqual(self.widget.required, True)
98        return
99
100    def test_subwidgets_exist(self):
101        # make sure we have three sub widgets
102        sub_widget1 = self.widget.widgets['country']
103        sub_widget2 = self.widget.widgets['area']
104        sub_widget3 = self.widget.widgets['extension']
105        self.assertTrue(isinstance(sub_widget1, TextWidget))
106        self.assertTrue(isinstance(sub_widget2, TextWidget))
107        self.assertTrue(isinstance(sub_widget3, TextWidget))
108        return
109
110    def test_set_rendered_value(self):
111        # make sure we render values correctly
112        self.widget.setRenderedValue(u'123-456-1234567')
113        self.assertEqual(
114            self.widget(),
115            (u'+<input class="textType" id="field.foo.country"'
116             u' name="field.foo.country" size="3" type="text" value="123" '
117             u' />'
118             u'&nbsp;&mdash;&nbsp;\n'
119             u'<input class="textType" id="field.foo.area"'
120             u' name="field.foo.area" size="5" type="text" value="456" '
121             u' />'
122             u'&nbsp;&mdash;&nbsp;\n'
123             u'<input class="textType" id="field.foo.extension"'
124             u' name="field.foo.extension" size="10" type="text"'
125             u' value="1234567"  />\n'))
126        return
127
128    def test_set_prefix_default(self):
129        # prefix determines the name of widget and its subwidgets.
130        self.assertEqual(self.widget.name, 'field.foo')
131        self.assertEqual(self.widget.widgets['country'].name,
132                         'field.foo.country')
133        self.assertEqual(self.widget.widgets['area'].name,
134                         'field.foo.area')
135        self.assertEqual(self.widget.widgets['extension'].name,
136                         'field.foo.extension')
137        return
138
139    def test_set_prefix_changed(self):
140        # when we set the prefix, widget names change
141        self.widget.setPrefix('test.')
142        self.assertEqual(self.widget.name, 'test.foo')
143        self.assertEqual(self.widget.widgets['country'].name,
144                         'test.foo.country')
145        self.assertEqual(self.widget.widgets['area'].name,
146                         'test.foo.area')
147        self.assertEqual(self.widget.widgets['extension'].name,
148                         'test.foo.extension')
149        return
150
151    def test_set_prefix_changed_no_dot(self):
152        # when we try to set a name without trailing dot, one will be
153        # inserted automatically
154        self.widget.setPrefix('test')
155        self.assertEqual(self.widget.name, 'test.foo')
156        self.assertEqual(self.widget.widgets['country'].name,
157                         'test.foo.country')
158        self.assertEqual(self.widget.widgets['area'].name,
159                         'test.foo.area')
160        self.assertEqual(self.widget.widgets['extension'].name,
161                         'test.foo.extension')
162        return
163
164    def test_get_input_value(self):
165        # we get a string when we want the input value
166        request = TestRequest(
167            form={
168                'field.foo.country': '123',
169                'field.foo.area': '456',
170                'field.foo.extension': '12345'
171                })
172        widget = PhoneWidget(self.field, request)
173        value = widget.getInputValue()
174        self.assertEqual(value, '123-456-12345')
175        return
176
177    def test_get_input_value_invalid(self):
178        # we get errors when valid data is sent
179        request = TestRequest(
180            form={
181                'field.foo.country': 'not-a-number',
182                'field.foo.area': '456',
183                'field.foo.extension': '12345'
184                })
185        widget = PhoneWidget(self.field, request)
186        self.assertRaises(
187            WidgetInputError,
188            widget.getInputValue)
189        return
190
191    def test_apply_changes(self):
192        # we can apply passed-in numbers to content objects. The
193        # widget is smart enough to detect whether the values really
194        # changed.
195        class Content(object):
196            field = None
197        content = Content()
198        request = TestRequest(form={
199                'field.foo.country': '123',
200                'field.foo.area': '456',
201                'field.foo.extension': '7890'})
202        widget = PhoneWidget(self.field, request)
203        result1 = widget.applyChanges(content)
204        result2 = widget.applyChanges(content)
205        self.assertEqual(result1, True)
206        self.assertEqual(content.foo, u'123-456-7890')
207        self.assertEqual(result2, False)
208        return
209
210    def test_has_input(self):
211        # we can check whether there is input without actually validating.
212        request = TestRequest(form={
213                'field.foo.country': '123'})
214        widget = PhoneWidget(self.field, request)
215        result = widget.hasInput()
216        self.assertEqual(result, False)
217
218        request = TestRequest(form={
219                'field.foo.area': '123'})
220        widget = PhoneWidget(self.field, request)
221        result = widget.hasInput()
222        self.assertEqual(result, False)
223
224        request = TestRequest(form={
225                'field.foo.extension': '123567'})
226        widget = PhoneWidget(self.field, request)
227        result = widget.hasInput()
228        self.assertEqual(result, False)
229
230        request = TestRequest(form={
231                'field.foo.country': '123',
232                'field.foo.area': '456',
233                'field.foo.extension': '7890'})
234        widget = PhoneWidget(self.field, request)
235        result = widget.hasInput()
236        self.assertEqual(result, True)
237
238        self.assertEqual(self.widget.hasInput(), False)
239        return
240
241    def test_has_valid_input(self):
242        # we can check for input also including validation
243        request = TestRequest(form={
244                'field.foo.country': '123'})
245        widget = PhoneWidget(self.field, request)
246        result = widget.hasValidInput()
247        self.assertEqual(result, False)
248
249        request = TestRequest(form={
250                'field.foo.area': '123'})
251        widget = PhoneWidget(self.field, request)
252        result = widget.hasValidInput()
253        self.assertEqual(result, False)
254
255        request = TestRequest(form={
256                'field.foo.extension': '123567'})
257        widget = PhoneWidget(self.field, request)
258        result = widget.hasValidInput()
259        self.assertEqual(result, False)
260
261        request = TestRequest(form={
262                'field.foo.country': '123',
263                'field.foo.area': '456',
264                'field.foo.extension': '7890'})
265        widget = PhoneWidget(self.field, request)
266        result = widget.hasValidInput()
267        self.assertEqual(result, True)
268
269        self.assertEqual(self.widget.hasValidInput(), False)
270        return
271
272    def test_hidden(self):
273        # we can render output as hidden field(s)
274        self.widget.setRenderedValue(u'123-456-1234567')
275        self.assertEqual(
276            self.widget.hidden(),
277            (u'<input class="hiddenType" id="field.foo.country"'
278             u' name="field.foo.country" type="hidden" value="123" '
279             u' />'
280             u'\n'
281             u'<input class="hiddenType" id="field.foo.area"'
282             u' name="field.foo.area" type="hidden" value="456" '
283             u' />'
284             u'\n'
285             u'<input class="hiddenType" id="field.foo.extension"'
286             u' name="field.foo.extension" type="hidden"'
287             u' value="1234567"  />'))
288        return
289
290    def test_error_extension(self):
291        # the widget can handle input errors in extension subwidget
292
293        # extension field too short
294        request = TestRequest(form={
295                'field.foo.country': '123',
296                'field.foo.area': '456',
297                'field.foo.extension': '0'})
298        widget = PhoneWidget(self.field, request)
299        try:
300            widget.getInputValue()
301            self.fail('No error raised')
302        except WidgetInputError, e:
303            pass
304        self.assertEqual(
305            e.__repr__(),
306            ("WidgetInputError("
307             "'extension', u'Direct Line', ConstraintNotSatisfied(u'0'))"))
308        self.assertEqual(
309            widget.error(),
310            u'<span class="error">Constraint not satisfied</span>')
311        return
312
313
314    def test_error_area(self):
315        # the widget can handle input errors in area code subwidget
316
317        # area code contains illegal chars
318        request = TestRequest(form={
319                'field.foo.country': '123',
320                'field.foo.area': 'no-number',
321                'field.foo.extension': '12345'})
322        widget = PhoneWidget(self.field, request)
323        try:
324            widget.getInputValue()
325            self.fail('No error raised')
326        except WidgetInputError, e:
327            pass
328        self.assertEqual(
329            e.__repr__(),
330            ("WidgetInputError("
331             "'area', u'Area Code', ConstraintNotSatisfied(u'no-number'))"))
332        self.assertEqual(
333            widget.error(),
334            u'<span class="error">Constraint not satisfied</span>')
335        return
336
337    def test_error_country(self):
338        # the widget can handle input errors in country code subwidget
339
340        # invalid country code
341        request = TestRequest(form={
342                'field.foo.country': 'XXX',
343                'field.foo.area': '456',
344                'field.foo.extension': '12345'})
345        widget = PhoneWidget(self.field, request)
346        try:
347            widget.getInputValue()
348            self.fail('No error raised')
349        except WidgetInputError, e:
350            pass
351        self.assertEqual(
352            e.__repr__(),
353            ("WidgetInputError("
354             "'country', u'Country Code', ConstraintNotSatisfied(u'XXX'))"))
355        self.assertEqual(
356            widget.error(),
357            u'<span class="error">Constraint not satisfied</span>')
358        return
359
360    def test_render_wo_data(self):
361        # when no data was submitted, the content data will be displayed
362        request = TestRequest(form={})
363        self.content.foo = u'11-222-3333'
364        widget = PhoneWidget(self.field, request)
365        self.assertEqual(
366            widget(),
367            (u'+<input class="textType" id="field.foo.country"'
368             u' name="field.foo.country" size="3" type="text" value="11" '
369             u' />'
370             u'&nbsp;&mdash;&nbsp;\n'
371             u'<input class="textType" id="field.foo.area"'
372             u' name="field.foo.area" size="5" type="text" value="222" '
373             u' />'
374             u'&nbsp;&mdash;&nbsp;\n'
375             u'<input class="textType" id="field.foo.extension"'
376             u' name="field.foo.extension" size="10" type="text"'
377             u' value="3333"  />\n'))
378        return
379
380    def test_render_with_data(self):
381        # when data was in the request, it will override any content value
382        request = TestRequest(form={
383                'field.foo.country': '11',
384                'field.foo.area': '222',
385                'field.foo.extension': '3333'})
386        self.content.foo = u'22-333-4444'
387        widget = PhoneWidget(self.field, request)
388        self.assertEqual(
389            widget(),
390            (u'+<input class="textType" id="field.foo.country"'
391             u' name="field.foo.country" size="3" type="text" value="11" '
392             u' />'
393             u'&nbsp;&mdash;&nbsp;\n'
394             u'<input class="textType" id="field.foo.area"'
395             u' name="field.foo.area" size="5" type="text" value="222" '
396             u' />'
397             u'&nbsp;&mdash;&nbsp;\n'
398             u'<input class="textType" id="field.foo.extension"'
399             u' name="field.foo.extension" size="10" type="text"'
400             u' value="3333"  />\n'))
401        return
402
403    def test_render_changed_prefix(self):
404        # when the prefix is changed, the subwidgets will reflect that
405        # properly. This tests a regression: if setPrefix was called
406        # on the phone widget, the subwidgets were already assuming
407        # that there is no data in the request
408        request = TestRequest(form={
409                'field.foo.country': '11',
410                'field.foo.area': '222',
411                'field.foo.extension': '3333'})
412        self.content.foo = u'22-333-4444'
413        widget = PhoneWidget(self.field, request)
414        # when setting a wrong prefix (not in the form), subwidgets
415        # will display the content values assuming (correctly) there
416        # is no data sent for them in the request.
417        widget.setPrefix('not-existent.')
418        self.assertTrue('value="4444"' in widget())
419        # when setting the right prefix, subwidgets will display the
420        # sent form values and not the content values.
421        widget.setPrefix('field.')
422        self.assertTrue('value="3333"' in widget())
423        return
Note: See TracBrowser for help on using the repository browser.