source: main/waeup.sirp/trunk/src/waeup/sirp/accesscodes/tests/test_accesscodes.py @ 6479

Last change on this file since 6479 was 6471, checked in by Henrik Bettermann, 13 years ago

Produce more user friendly and shorter object history messages.

File size: 10.9 KB
Line 
1##
2## test_accesscodes.py
3## Login : <uli@pu.smp.net>
4## Started on  Sun Jun 12 13:07:58 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##
22import doctest
23import os
24import re
25import shutil
26import tempfile
27import unittest
28
29from datetime import datetime
30from hurry.workflow.interfaces import InvalidTransitionError, IWorkflowState
31from zope.app.testing.functional import (
32    FunctionalTestCase, FunctionalTestSetup, getRootFolder)
33from zope.component.hooks import setSite, clearSite
34from zope.interface.verify import verifyObject, verifyClass
35from zope.testing import renormalizing
36from waeup.sirp.app import University
37from waeup.sirp.interfaces import IObjectHistory
38from waeup.sirp.testing import FunctionalLayer
39from waeup.sirp.accesscodes.accesscodes import (
40    AccessCodeBatch, get_access_code, invalidate_accesscode, AccessCode,
41    disable_accesscode, reenable_accesscode, fire_transition,
42    AccessCodeBatchContainer,)
43from waeup.sirp.accesscodes.interfaces import (
44    IAccessCode, IAccessCodeBatch,  IAccessCodeBatchContainer,)
45from waeup.sirp.accesscodes.workflow import INITIALIZED, USED, DISABLED
46
47
48
49
50class AccessCodeHelpersTests(FunctionalTestCase):
51    # Tests for helpers like get_access_code, disable_accesscode, ...
52
53    layer = FunctionalLayer
54
55    def setUp(self):
56        super(AccessCodeHelpersTests, self).setUp()
57
58        # Prepopulate ZODB
59        app = University()
60        self.dc_root = tempfile.mkdtemp()
61        app['datacenter'].setStoragePath(self.dc_root)
62
63        # Prepopulate the ZODB...
64        self.getRootFolder()['app'] = app
65        self.app = self.getRootFolder()['app']
66
67        # Create batch
68        batch = AccessCodeBatch('now', 'manfred', 'APP', 6.6, 0)
69        self.app['accesscodes'].addBatch(batch)
70
71        # Fill batch with accesscodes
72        batch.addAccessCode(0, '11111111')
73        batch.addAccessCode(1, '22222222')
74        batch.addAccessCode(2, '33333333')
75        self.ac1 = batch.getAccessCode('APP-1-11111111')
76        self.ac2 = batch.getAccessCode('APP-1-22222222')
77        self.ac3 = batch.getAccessCode('APP-1-33333333')
78
79        setSite(self.app)
80        return
81
82    def tearDown(self):
83        shutil.rmtree(self.dc_root)
84        super(AccessCodeHelpersTests, self).tearDown()
85        return
86
87    def test_get_access_code(self):
88        ac = get_access_code('APP-1-11111111')
89        assert ac is self.ac1
90
91    def test_get_access_code_not_string(self):
92        ac = get_access_code(object())
93        assert ac is None
94
95    def test_get_access_code_no_proper_pin(self):
96        ac = get_access_code('APP-without_pin')
97        assert ac is None
98
99    def test_get_access_code_invalid_batch_num(self):
100        ac = get_access_code('APP-invalid-11111111')
101        assert ac is None
102
103    def test_get_access_code_invalid_pin(self):
104        ac = get_access_code('APP-1-notexistent')
105        assert ac is None
106
107    def test_invalidate_accesscode(self):
108        assert self.ac1.state != USED
109        result = invalidate_accesscode('APP-1-11111111')
110        assert self.ac1.state == USED
111        assert result is True
112
113    def test_disable_accesscode_unused(self):
114        # we can disable initialized acs
115        assert self.ac1.state != USED
116        disable_accesscode('APP-1-11111111')
117        assert self.ac1.state == DISABLED
118
119    def test_disable_accesscode_used(self):
120        # we can disable already used acs
121        assert self.ac1.state != DISABLED
122        invalidate_accesscode('APP-1-11111111')
123        disable_accesscode('APP-1-11111111')
124        assert self.ac1.state == DISABLED
125
126    def test_reenable_accesscode(self):
127        # we can reenable disabled acs
128        disable_accesscode('APP-1-11111111')
129        result = reenable_accesscode('APP-1-11111111')
130        assert result is True
131        assert self.ac1.state != USED
132
133    def test_fire_transition(self):
134        # we can fire transitions generally
135        fire_transition('APP-1-11111111', 'use')
136        assert IWorkflowState(self.ac1).getState() is USED
137
138    def test_fire_transition_toward(self):
139        # the `toward` keyword is respected
140        fire_transition('APP-1-11111111', DISABLED, toward=True)
141        assert IWorkflowState(self.ac1).getState() is DISABLED
142
143    def test_fire_transition_no_site(self):
144        # when no site is available, we will get a TypeError
145        clearSite()
146        self.assertRaises(
147            KeyError,
148            fire_transition, 'APP-1-11111111', 'use')
149
150    def test_fire_transition_broken_ac_id(self):
151        # if we get an invalid access code id (of wrong format) we get
152        # ValueErrors
153        self.assertRaises(
154            ValueError,
155            fire_transition, '11111111', 'use')
156
157    def test_fire_transition_invalid_batch_id(self):
158        # if we request a non-existent batch_id, we'll get a KeyError
159        self.assertRaises(
160            KeyError,
161            fire_transition, 'FOO-1-11111111', 'use')
162
163    def test_fire_transition_invalid_ac(self):
164        # if we request a non-exitent access-code, we'll get a KeyError
165        self.assertRaises(
166            KeyError,
167            fire_transition, 'APP-1-NONSENSE', 'use')
168
169    def test_fire_transition_undef_trans_id(self):
170        # asking for undefined transition id means a KeyError
171        self.assertRaises(
172            KeyError,
173            fire_transition, 'APP-1-11111111', 'nonsense')
174
175    def test_fire_transition_invalid_transition(self):
176        # asking for a forbidden transition will result in
177        # InvalidTransitionError
178        self.assertRaises(
179            InvalidTransitionError,
180            fire_transition, 'APP-1-11111111', 'init') # already initialized
181
182    def test_fire_transition_comment(self):
183        # when we request a comment, it will also appear in history
184        fire_transition('APP-1-11111111', 'use', comment='Hi there!')
185        history = IObjectHistory(self.ac1)
186        msgs = history.messages
187        assert 'Hi there!' in msgs[-1]
188
189    def test_fire_transition_no_comment(self):
190        # without comment, the history should be without trailing garbage
191        fire_transition('APP-1-11111111', 'use')
192        history = IObjectHistory(self.ac1)
193        msgs = history.messages
194        assert msgs[-1].endswith('AC used by system')
195
196class AccessCodeTests(FunctionalTestCase):
197    # Tests for AccessCode class
198
199    layer = FunctionalLayer
200
201    def setUp(self):
202        super(AccessCodeTests, self).setUp()
203
204        # Prepopulate ZODB
205        app = University()
206        self.dc_root = tempfile.mkdtemp()
207        app['datacenter'].setStoragePath(self.dc_root)
208
209        # Prepopulate the ZODB...
210        self.getRootFolder()['app'] = app
211        self.app = self.getRootFolder()['app']
212
213        # Create batch
214        batch = AccessCodeBatch('now', 'manfred', 'APP', 6.6, 0)
215        self.app['accesscodes'].addBatch(batch)
216
217        # Fill batch with accesscodes
218        batch.addAccessCode(0, '11111111')
219
220        self.ac1 = batch.getAccessCode('APP-1-11111111')
221        setSite(self.app)
222        return
223
224    def tearDown(self):
225        shutil.rmtree(self.dc_root)
226        super(AccessCodeTests, self).tearDown()
227        return
228
229    def test_iface(self):
230        # AccessCodes fullfill their iface promises.
231        ac = AccessCode('1', '12345678')
232        assert verifyObject(IAccessCode, ac)
233        assert verifyClass(IAccessCode, AccessCode)
234
235    def test_history(self):
236        # Access codes have a history.
237        match = re.match(
238            '^....-..-.. ..:..:.. - AC initialized by system',
239            self.ac1.history)
240        assert match is not None
241
242class AccessCodeBatchTests(FunctionalTestCase):
243    # Tests for AccessCodeBatch class
244
245    layer = FunctionalLayer
246
247    def setUp(self):
248        super(AccessCodeBatchTests, self).setUp()
249
250        # Prepopulate ZODB
251        app = University()
252        self.dc_root = tempfile.mkdtemp()
253        app['datacenter'].setStoragePath(self.dc_root)
254
255        # Prepopulate the ZODB...
256        self.getRootFolder()['app'] = app
257        self.app = self.getRootFolder()['app']
258
259        setSite(self.app)
260        return
261
262    def tearDown(self):
263        shutil.rmtree(self.dc_root)
264        super(AccessCodeBatchTests, self).tearDown()
265        return
266
267    def test_iface(self):
268        batch = AccessCodeBatch(
269            datetime(2009, 12, 23), 'Fred','APP', 12.12, 3, num=10)
270        assert verifyObject(IAccessCodeBatch, batch)
271        assert verifyClass(IAccessCodeBatch, AccessCodeBatch)
272
273class AccessCodeBatchContainerTests(FunctionalTestCase):
274    # Tests for AccessCodeContainer class
275
276    layer = FunctionalLayer
277
278    def setUp(self):
279        super(AccessCodeBatchContainerTests, self).setUp()
280
281        # Prepopulate ZODB
282        app = University()
283        self.dc_root = tempfile.mkdtemp()
284        app['datacenter'].setStoragePath(self.dc_root)
285
286        # Prepopulate the ZODB...
287        self.getRootFolder()['app'] = app
288        self.app = self.getRootFolder()['app']
289
290        setSite(self.app)
291        return
292
293    def tearDown(self):
294        shutil.rmtree(self.dc_root)
295        super(AccessCodeBatchContainerTests, self).tearDown()
296        return
297
298    def test_iface(self):
299        accesscodes = AccessCodeBatchContainer()
300        assert verifyObject(IAccessCodeBatchContainer, accesscodes)
301        assert verifyClass(IAccessCodeBatchContainer, AccessCodeBatchContainer)
302
303
304checker = renormalizing.RENormalizing([
305        (re.compile('[\d]{10}'), '<10-DIGITS>'),
306        ])
307
308def setUp(test):
309    FunctionalTestSetup().setUp()
310
311def tearDown(self, test=None):
312    FunctionalTestSetup().tearDown()
313
314
315
316def test_suite():
317    suite = unittest.TestSuite()
318    for testcase in [
319        AccessCodeHelpersTests,
320        AccessCodeTests,
321        AccessCodeBatchTests,
322        AccessCodeBatchContainerTests,
323        ]:
324        suite.addTests(unittest.TestLoader().loadTestsFromTestCase(testcase))
325    for filename in [
326        #'accesscodes.txt',
327        'browser.txt'
328        ]:
329        path = os.path.join(
330            os.path.dirname(os.path.dirname(__file__)), filename)
331        test = doctest.DocFileSuite(
332            path,
333            module_relative=False,
334            setUp=setUp, tearDown=tearDown,
335            globs = dict(getRootFolder = getRootFolder),
336            optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
337            checker = checker,
338            )
339        test.layer = FunctionalLayer
340        suite.addTest(test)
341    return suite
Note: See TracBrowser for help on using the repository browser.