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

Last change on this file since 7415 was 7415, checked in by Henrik Bettermann, 13 years ago
  • Property svn:keywords set to Id
File size: 18.0 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: test_phonewidget.py 7415 2011-12-21 07:15:47Z henrik $
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
51    bar = schema.TextLine(
52        title = u'Phone',
53        description = u'Phone number (not required)',
54        required = False)
55
56class SampleContent:
57    implements(ISampleContent)
58
59class PhoneWidgetTests(unittest.TestCase):
60    # Tests for phone widget
61
62    def setUp(self):
63        placefulSetUp()
64
65        # register TextLine views (so that subwidgets can be rendered)
66        provideAdapter(
67            TextWidget, (ITextLine, IDefaultBrowserLayer), IInputWidget)
68        # errors in forms
69        provideAdapter(
70            WidgetInputErrorView, (IWidgetInputError, IDefaultBrowserLayer),
71            IWidgetInputErrorView)
72
73        # setup some sample content to bind to (only neccessary for
74        # some of the tests)
75        self.content = SampleContent()
76        self.field = ISampleContent['foo']
77        self.field = self.field.bind(self.content)
78        self.field_nonreq = ISampleContent['bar']
79        self.field_nonreq = self.field_nonreq.bind(self.content)
80
81        # create an empty request. We need one to create a widget
82        self.request = TestRequest()
83        self.widget = PhoneWidget(self.field, self.request)
84        self.widget_nonreq = PhoneWidget(self.field_nonreq, self.request)
85        return
86
87    def tearDown(self):
88        placefulTearDown()
89        return
90
91    def test_ifaces(self):
92        # make sure we fullfill interface contracts
93        verify.verifyClass(IBrowserWidget, PhoneWidget)
94        verify.verifyClass(IInputWidget, PhoneWidget)
95        verify.verifyObject(IBrowserWidget, self.widget)
96        verify.verifyObject(IInputWidget, self.widget)
97        return
98
99    def test_attribs_set(self):
100        # make sure the public attributes are set correctly
101        self.assertEqual(self.widget.name, 'field.foo')
102        self.assertEqual(self.widget.label, u'Phone')
103        self.assertEqual(self.widget.hint, u'Phone number')
104        self.assertEqual(self.widget.visible, True)
105        self.assertEqual(self.widget.required, True)
106        self.assertEqual(self.widget_nonreq.required, False)
107        return
108
109    def test_subwidgets_exist(self):
110        # make sure we have three sub widgets
111        sub_widget1 = self.widget.widgets['country']
112        sub_widget2 = self.widget.widgets['area']
113        sub_widget3 = self.widget.widgets['extension']
114        self.assertTrue(isinstance(sub_widget1, TextWidget))
115        self.assertTrue(isinstance(sub_widget2, TextWidget))
116        self.assertTrue(isinstance(sub_widget3, TextWidget))
117        return
118
119    def test_set_rendered_value(self):
120        # make sure we render values correctly
121        self.widget.setRenderedValue(u'123-456-1234567')
122        self.assertEqual(
123            self.widget(),
124            (u'+<input class="textType" id="field.foo.country"'
125             u' name="field.foo.country" size="3" type="text" value="123" '
126             u' />'
127             u'&nbsp;&mdash;&nbsp;\n'
128             u'<input class="textType" id="field.foo.area"'
129             u' name="field.foo.area" size="5" type="text" value="456" '
130             u' />'
131             u'&nbsp;&mdash;&nbsp;\n'
132             u'<input class="textType" id="field.foo.extension"'
133             u' name="field.foo.extension" size="10" type="text"'
134             u' value="1234567"  />\n'))
135        return
136
137    def test_set_prefix_default(self):
138        # prefix determines the name of widget and its subwidgets.
139        self.assertEqual(self.widget.name, 'field.foo')
140        self.assertEqual(self.widget.widgets['country'].name,
141                         'field.foo.country')
142        self.assertEqual(self.widget.widgets['area'].name,
143                         'field.foo.area')
144        self.assertEqual(self.widget.widgets['extension'].name,
145                         'field.foo.extension')
146        return
147
148    def test_set_prefix_changed(self):
149        # when we set the prefix, widget names change
150        self.widget.setPrefix('test.')
151        self.assertEqual(self.widget.name, 'test.foo')
152        self.assertEqual(self.widget.widgets['country'].name,
153                         'test.foo.country')
154        self.assertEqual(self.widget.widgets['area'].name,
155                         'test.foo.area')
156        self.assertEqual(self.widget.widgets['extension'].name,
157                         'test.foo.extension')
158        return
159
160    def test_set_prefix_changed_no_dot(self):
161        # when we try to set a name without trailing dot, one will be
162        # inserted automatically
163        self.widget.setPrefix('test')
164        self.assertEqual(self.widget.name, 'test.foo')
165        self.assertEqual(self.widget.widgets['country'].name,
166                         'test.foo.country')
167        self.assertEqual(self.widget.widgets['area'].name,
168                         'test.foo.area')
169        self.assertEqual(self.widget.widgets['extension'].name,
170                         'test.foo.extension')
171        return
172
173    def test_get_input_value(self):
174        # we get a string when we want the input value
175        request = TestRequest(
176            form={
177                'field.foo.country': '123',
178                'field.foo.area': '456',
179                'field.foo.extension': '12345'
180                })
181        widget = PhoneWidget(self.field, request)
182        value = widget.getInputValue()
183        self.assertEqual(value, '123-456-12345')
184        return
185
186    def test_get_input_value_invalid(self):
187        # we get errors when valid data is sent
188        request = TestRequest(
189            form={
190                'field.foo.country': 'not-a-number',
191                'field.foo.area': '456',
192                'field.foo.extension': '12345'
193                })
194        widget = PhoneWidget(self.field, request)
195        self.assertRaises(
196            WidgetInputError,
197            widget.getInputValue)
198        return
199
200    def test_apply_changes(self):
201        # we can apply passed-in numbers to content objects. The
202        # widget is smart enough to detect whether the values really
203        # changed.
204        class Content(object):
205            field = None
206        content = Content()
207        request = TestRequest(form={
208                'field.foo.country': '123',
209                'field.foo.area': '456',
210                'field.foo.extension': '7890'})
211        widget = PhoneWidget(self.field, request)
212        result1 = widget.applyChanges(content)
213        result2 = widget.applyChanges(content)
214        self.assertEqual(result1, True)
215        self.assertEqual(content.foo, u'123-456-7890')
216        self.assertEqual(result2, False)
217        return
218
219    def test_has_input(self):
220        # we can check whether there is input without actually validating.
221        request = TestRequest(form={
222                'field.foo.country': '123'})
223        widget = PhoneWidget(self.field, request)
224        result = widget.hasInput()
225        self.assertEqual(result, False)
226
227        request = TestRequest(form={
228                'field.foo.area': '123'})
229        widget = PhoneWidget(self.field, request)
230        result = widget.hasInput()
231        self.assertEqual(result, False)
232
233        request = TestRequest(form={
234                'field.foo.extension': '123567'})
235        widget = PhoneWidget(self.field, request)
236        result = widget.hasInput()
237        self.assertEqual(result, False)
238
239        request = TestRequest(form={
240                'field.foo.country': '123',
241                'field.foo.area': '456',
242                'field.foo.extension': '7890'})
243        widget = PhoneWidget(self.field, request)
244        result = widget.hasInput()
245        self.assertEqual(result, True)
246
247        self.assertEqual(self.widget.hasInput(), False)
248        return
249
250    def test_has_valid_input(self):
251        # we can check for input also including validation
252        request = TestRequest(form={
253                'field.foo.country': '123'})
254        widget = PhoneWidget(self.field, request)
255        result = widget.hasValidInput()
256        self.assertEqual(result, False)
257
258        request = TestRequest(form={
259                'field.foo.area': '123'})
260        widget = PhoneWidget(self.field, request)
261        result = widget.hasValidInput()
262        self.assertEqual(result, False)
263
264        request = TestRequest(form={
265                'field.foo.extension': '123567'})
266        widget = PhoneWidget(self.field, request)
267        result = widget.hasValidInput()
268        self.assertEqual(result, False)
269
270        request = TestRequest(form={
271                'field.foo.country': '123',
272                'field.foo.area': '456',
273                'field.foo.extension': '7890'})
274        widget = PhoneWidget(self.field, request)
275        result = widget.hasValidInput()
276        self.assertEqual(result, True)
277
278        self.assertEqual(self.widget.hasValidInput(), False)
279        return
280
281    def test_hidden(self):
282        # we can render output as hidden field(s)
283        self.widget.setRenderedValue(u'123-456-1234567')
284        self.assertEqual(
285            self.widget.hidden(),
286            (u'<input class="hiddenType" id="field.foo.country"'
287             u' name="field.foo.country" type="hidden" value="123" '
288             u' />'
289             u'\n'
290             u'<input class="hiddenType" id="field.foo.area"'
291             u' name="field.foo.area" type="hidden" value="456" '
292             u' />'
293             u'\n'
294             u'<input class="hiddenType" id="field.foo.extension"'
295             u' name="field.foo.extension" type="hidden"'
296             u' value="1234567"  />'))
297        return
298
299    def test_error_extension(self):
300        # the widget can handle input errors in extension subwidget
301
302        # extension field too short
303        request = TestRequest(form={
304                'field.foo.country': '123',
305                'field.foo.area': '456',
306                'field.foo.extension': '0'})
307        widget = PhoneWidget(self.field, request)
308        try:
309            widget.getInputValue()
310            self.fail('No error raised')
311        except WidgetInputError, e:
312            pass
313        self.assertEqual(
314            e.__repr__(),
315            ("WidgetInputError("
316             "'extension', u'Direct Line', ConstraintNotSatisfied(u'0'))"))
317        self.assertEqual(
318            widget.error(),
319            u'<span class="error">Constraint not satisfied</span>')
320        return
321
322
323    def test_error_area(self):
324        # the widget can handle input errors in area code subwidget
325
326        # area code contains illegal chars
327        request = TestRequest(form={
328                'field.foo.country': '123',
329                'field.foo.area': 'no-number',
330                'field.foo.extension': '12345'})
331        widget = PhoneWidget(self.field, request)
332        try:
333            widget.getInputValue()
334            self.fail('No error raised')
335        except WidgetInputError, e:
336            pass
337        self.assertEqual(
338            e.__repr__(),
339            ("WidgetInputError("
340             "'area', u'Area Code', ConstraintNotSatisfied(u'no-number'))"))
341        self.assertEqual(
342            widget.error(),
343            u'<span class="error">Constraint not satisfied</span>')
344        return
345
346    def test_error_country(self):
347        # the widget can handle input errors in country code subwidget
348
349        # invalid country code
350        request = TestRequest(form={
351                'field.foo.country': 'XXX',
352                'field.foo.area': '456',
353                'field.foo.extension': '12345'})
354        widget = PhoneWidget(self.field, request)
355        try:
356            widget.getInputValue()
357            self.fail('No error raised')
358        except WidgetInputError, e:
359            pass
360        self.assertEqual(
361            e.__repr__(),
362            ("WidgetInputError("
363             "'country', u'Country Code', ConstraintNotSatisfied(u'XXX'))"))
364        self.assertEqual(
365            widget.error(),
366            u'<span class="error">Constraint not satisfied</span>')
367        return
368
369    def test_render_wo_data(self):
370        # when no data was submitted, the content data will be displayed
371        request = TestRequest(form={})
372        self.content.foo = u'11-222-3333'
373        widget = PhoneWidget(self.field, request)
374        self.assertEqual(
375            widget(),
376            (u'+<input class="textType" id="field.foo.country"'
377             u' name="field.foo.country" size="3" type="text" value="11" '
378             u' />'
379             u'&nbsp;&mdash;&nbsp;\n'
380             u'<input class="textType" id="field.foo.area"'
381             u' name="field.foo.area" size="5" type="text" value="222" '
382             u' />'
383             u'&nbsp;&mdash;&nbsp;\n'
384             u'<input class="textType" id="field.foo.extension"'
385             u' name="field.foo.extension" size="10" type="text"'
386             u' value="3333"  />\n'))
387        return
388
389    def test_render_with_data(self):
390        # when data was in the request, it will override any content value
391        request = TestRequest(form={
392                'field.foo.country': '11',
393                'field.foo.area': '222',
394                'field.foo.extension': '3333'})
395        self.content.foo = u'22-333-4444'
396        widget = PhoneWidget(self.field, request)
397        self.assertEqual(
398            widget(),
399            (u'+<input class="textType" id="field.foo.country"'
400             u' name="field.foo.country" size="3" type="text" value="11" '
401             u' />'
402             u'&nbsp;&mdash;&nbsp;\n'
403             u'<input class="textType" id="field.foo.area"'
404             u' name="field.foo.area" size="5" type="text" value="222" '
405             u' />'
406             u'&nbsp;&mdash;&nbsp;\n'
407             u'<input class="textType" id="field.foo.extension"'
408             u' name="field.foo.extension" size="10" type="text"'
409             u' value="3333"  />\n'))
410        return
411
412    def test_render_changed_prefix(self):
413        # when the prefix is changed, the subwidgets will reflect that
414        # properly. This tests a regression: if setPrefix was called
415        # on the phone widget, the subwidgets were already assuming
416        # that there is no data in the request
417        request = TestRequest(form={
418                'field.foo.country': '11',
419                'field.foo.area': '222',
420                'field.foo.extension': '3333'})
421        self.content.foo = u'22-333-4444'
422        widget = PhoneWidget(self.field, request)
423        # when setting a wrong prefix (not in the form), subwidgets
424        # will display the content values assuming (correctly) there
425        # is no data sent for them in the request.
426        widget.setPrefix('not-existent.')
427        self.assertTrue('value="4444"' in widget())
428        # when setting the right prefix, subwidgets will display the
429        # sent form values and not the content values.
430        widget.setPrefix('field.')
431        self.assertTrue('value="3333"' in widget())
432        return
433
434    def test_render_changed_prefix(self):
435        # when the prefix is changed, the subwidgets will reflect that
436        # properly. This tests a regression: if setPrefix was called
437        # on the phone widget, the subwidgets were already assuming
438        # that there is no data in the request
439        request = TestRequest(form={
440                'field.foo.country': '11',
441                'field.foo.area': '222',
442                'field.foo.extension': '3333'})
443        self.content.foo = u'22-333-4444'
444        widget = PhoneWidget(self.field, request)
445        # when setting a wrong prefix (not in the form), subwidgets
446        # will display the content values assuming (correctly) there
447        # is no data sent for them in the request.
448        widget.setPrefix('not-existent.')
449        self.assertTrue('value="4444"' in widget())
450        # when setting the right prefix, subwidgets will display the
451        # sent form values and not the content values.
452        widget.setPrefix('field.')
453        self.assertTrue('value="3333"' in widget())
454        return
455
456    def test_non_required_no_input(self):
457        # if the bound field requires no input phone widget will cope
458        # with that.
459        class Content(object):
460            field = None
461
462        content = Content()
463        request = TestRequest(form={
464                'field.foo.country': '11',
465                'field.foo.area': '222',
466                'field.foo.extension': '3333'})
467        widget = PhoneWidget(self.field_nonreq, request)
468        result1 = widget.applyChanges(content)
469        result2 = widget.getInputValue()
470        self.assertEqual(result1, True)
471        # without input we get the default value set
472        self.assertEqual(content.bar, u'')
473        self.assertEqual(result2, u'')
474        return
Note: See TracBrowser for help on using the repository browser.