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

Last change on this file since 6461 was 6459, checked in by Henrik Bettermann, 14 years ago

Change structure of history messages (not sure if unicode strings are appropriate here).

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.status != USED
109        result = invalidate_accesscode('APP-1-11111111')
110        assert self.ac1.status == USED
111        assert result is True
112
113    def test_disable_accesscode_unused(self):
114        # we can disable initialized acs
115        assert self.ac1.status != USED
116        disable_accesscode('APP-1-11111111')
117        assert self.ac1.status == DISABLED
118
119    def test_disable_accesscode_used(self):
120        # we can disable already used acs
121        assert self.ac1.status != DISABLED
122        invalidate_accesscode('APP-1-11111111')
123        disable_accesscode('APP-1-11111111')
124        assert self.ac1.status == 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.status != 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('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            '^../../.... ..:..:.. - 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.