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

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

Remove trash.

File size: 12.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    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, FunctionalTestCase
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
48optionflags = (
49    doctest.REPORT_NDIFF + doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE)
50
51class AccessCodeHelpersTests(FunctionalTestCase):
52    # Tests for helpers like get_access_code, disable_accesscode, ...
53
54    layer = FunctionalLayer
55
56    def setUp(self):
57        super(AccessCodeHelpersTests, self).setUp()
58
59        # Prepopulate ZODB
60        app = University()
61        self.dc_root = tempfile.mkdtemp()
62        app['datacenter'].setStoragePath(self.dc_root)
63
64        # Prepopulate the ZODB...
65        self.getRootFolder()['app'] = app
66        self.app = self.getRootFolder()['app']
67
68        # Create batch
69        batch = AccessCodeBatch('now', 'manfred', 'APP', 6.6, 0)
70        self.app['accesscodes'].addBatch(batch)
71
72        # Fill batch with accesscodes
73        batch.addAccessCode(0, '11111111')
74        batch.addAccessCode(1, '22222222')
75        batch.addAccessCode(2, '33333333')
76        self.ac1 = batch.getAccessCode('APP-1-11111111')
77        self.ac2 = batch.getAccessCode('APP-1-22222222')
78        self.ac3 = batch.getAccessCode('APP-1-33333333')
79
80        setSite(self.app)
81        return
82
83    def tearDown(self):
84        shutil.rmtree(self.dc_root)
85        super(AccessCodeHelpersTests, self).tearDown()
86        return
87
88    def test_get_access_code(self):
89        ac = get_access_code('APP-1-11111111')
90        assert ac is self.ac1
91
92    def test_get_access_code_not_string(self):
93        ac = get_access_code(object())
94        assert ac is None
95
96    def test_get_access_code_no_proper_pin(self):
97        ac = get_access_code('APP-without_pin')
98        assert ac is None
99
100    def test_get_access_code_invalid_batch_num(self):
101        ac = get_access_code('APP-invalid-11111111')
102        assert ac is None
103
104    def test_get_access_code_invalid_pin(self):
105        ac = get_access_code('APP-1-notexistent')
106        assert ac is None
107
108    def test_invalidate_accesscode(self):
109        assert self.ac1.state != USED
110        result = invalidate_accesscode('APP-1-11111111')
111        assert self.ac1.state == USED
112        assert result is True
113
114    def test_disable_accesscode_unused(self):
115        # we can disable initialized acs
116        assert self.ac1.state != USED
117        disable_accesscode('APP-1-11111111')
118        assert self.ac1.state == DISABLED
119
120    def test_disable_accesscode_used(self):
121        # we can disable already used acs
122        assert self.ac1.state != DISABLED
123        invalidate_accesscode('APP-1-11111111')
124        disable_accesscode('APP-1-11111111')
125        assert self.ac1.state == DISABLED
126
127    def test_reenable_accesscode(self):
128        # we can reenable disabled acs
129        disable_accesscode('APP-1-11111111')
130        result = reenable_accesscode('APP-1-11111111')
131        assert result is True
132        assert self.ac1.state != USED
133
134    def test_fire_transition(self):
135        # we can fire transitions generally
136        fire_transition('APP-1-11111111', 'use')
137        assert IWorkflowState(self.ac1).getState() is USED
138
139    def test_fire_transition_toward(self):
140        # the `toward` keyword is respected
141        fire_transition('APP-1-11111111', DISABLED, toward=True)
142        assert IWorkflowState(self.ac1).getState() is DISABLED
143
144    def test_fire_transition_no_site(self):
145        # when no site is available, we will get a TypeError
146        clearSite()
147        self.assertRaises(
148            KeyError,
149            fire_transition, 'APP-1-11111111', 'use')
150
151    def test_fire_transition_broken_ac_id(self):
152        # if we get an invalid access code id (of wrong format) we get
153        # ValueErrors
154        self.assertRaises(
155            ValueError,
156            fire_transition, '11111111', 'use')
157
158    def test_fire_transition_invalid_batch_id(self):
159        # if we request a non-existent batch_id, we'll get a KeyError
160        self.assertRaises(
161            KeyError,
162            fire_transition, 'FOO-1-11111111', 'use')
163
164    def test_fire_transition_invalid_ac(self):
165        # if we request a non-exitent access-code, we'll get a KeyError
166        self.assertRaises(
167            KeyError,
168            fire_transition, 'APP-1-NONSENSE', 'use')
169
170    def test_fire_transition_undef_trans_id(self):
171        # asking for undefined transition id means a KeyError
172        self.assertRaises(
173            KeyError,
174            fire_transition, 'APP-1-11111111', 'nonsense')
175
176    def test_fire_transition_invalid_transition(self):
177        # asking for a forbidden transition will result in
178        # InvalidTransitionError
179        self.assertRaises(
180            InvalidTransitionError,
181            fire_transition, 'APP-1-11111111', 'init') # already initialized
182
183    def test_fire_transition_comment(self):
184        # when we request a comment, it will also appear in history
185        fire_transition('APP-1-11111111', 'use', comment='Hi there!')
186        history = IObjectHistory(self.ac1)
187        msgs = history.messages
188        assert 'Hi there!' in msgs[-1]
189
190    def test_fire_transition_no_comment(self):
191        # without comment, the history should be without trailing garbage
192        fire_transition('APP-1-11111111', 'use')
193        history = IObjectHistory(self.ac1)
194        msgs = history.messages
195        assert msgs[-1].endswith('AC used by system')
196
197class AccessCodeTests(FunctionalTestCase):
198    # Tests for AccessCode class
199
200    layer = FunctionalLayer
201
202    def setUp(self):
203        super(AccessCodeTests, self).setUp()
204
205        # Prepopulate ZODB
206        app = University()
207        self.dc_root = tempfile.mkdtemp()
208        app['datacenter'].setStoragePath(self.dc_root)
209
210        # Prepopulate the ZODB...
211        self.getRootFolder()['app'] = app
212        self.app = self.getRootFolder()['app']
213
214        # Create batch
215        batch = AccessCodeBatch('now', 'manfred', 'APP', 6.6, 0)
216        self.app['accesscodes'].addBatch(batch)
217
218        # Fill batch with accesscodes
219        batch.addAccessCode(0, '11111111')
220
221        self.ac1 = batch.getAccessCode('APP-1-11111111')
222        setSite(self.app)
223        return
224
225    def tearDown(self):
226        shutil.rmtree(self.dc_root)
227        super(AccessCodeTests, self).tearDown()
228        return
229
230    def test_iface(self):
231        # AccessCodes fullfill their iface promises.
232        ac = AccessCode('1', '12345678')
233        assert verifyObject(IAccessCode, ac)
234        assert verifyClass(IAccessCode, AccessCode)
235
236    def test_history(self):
237        # Access codes have a history.
238        match = re.match(
239            '^....-..-.. ..:..:.. - AC initialized by system',
240            self.ac1.history)
241        assert match is not None
242
243class AccessCodeBatchTests(FunctionalTestCase):
244    # Tests for AccessCodeBatch class
245
246    layer = FunctionalLayer
247
248    def setUp(self):
249        super(AccessCodeBatchTests, self).setUp()
250
251        # Prepopulate ZODB
252        app = University()
253        self.dc_root = tempfile.mkdtemp()
254        app['datacenter'].setStoragePath(self.dc_root)
255
256        # Prepopulate the ZODB...
257        self.getRootFolder()['app'] = app
258        self.app = self.getRootFolder()['app']
259
260        batch = AccessCodeBatch(    # create batch with zero entries
261            datetime.now(), 'testuser', 'FOO', 9.99, 0)
262        self.app['accesscodes'].addBatch(batch)
263
264        self.ac1 = AccessCode(0, '11111111')
265        self.ac2 = AccessCode(1, '22222222')
266        self.ac3 = AccessCode(2, '33333333')
267        batch['FOO-1-11111111'] = self.ac1
268        batch['FOO-1-22222222'] = self.ac2
269        batch['FOO-1-33333333'] = self.ac3
270        self.batch = batch
271
272        setSite(self.app)
273        return
274
275    def tearDown(self):
276        shutil.rmtree(self.dc_root)
277        super(AccessCodeBatchTests, self).tearDown()
278        return
279
280    def test_iface(self):
281        batch = AccessCodeBatch(
282            datetime(2009, 12, 23), 'Fred','APP', 12.12, 3, num=10)
283        assert verifyObject(IAccessCodeBatch, batch)
284        assert verifyClass(IAccessCodeBatch, AccessCodeBatch)
285
286    def test_csv_export(self):
287        # Make sure CSV export of accesscodes works
288        batch = self.batch
289        invalidate_accesscode('FOO-1-11111111', comment='comment with "quotes"')
290        disable_accesscode('FOO-1-33333333')
291        basename = batch.archive()
292        result_path = os.path.join(batch._getStoragePath(), basename)
293        expected = '''
294"prefix","serial","ac","state","history"
295"FOO","9.99","1","0"
296"FOO","0","FOO-1-11111111","used","<YYYY-MM-DD hh:mm:ss> - ..."
297"FOO","1","FOO-1-22222222","initialized","<YYYY-MM-DD hh:mm:ss> - ..."
298"FOO","2","FOO-1-33333333","disabled","<YYYY-MM-DD hh:mm:ss> - ..."
299'''[1:]
300        contents = open(result_path, 'rb').read()
301        self.assertMatches(expected, contents)
302
303class AccessCodeBatchContainerTests(FunctionalTestCase):
304    # Tests for AccessCodeContainer class
305
306    layer = FunctionalLayer
307
308    def setUp(self):
309        super(AccessCodeBatchContainerTests, self).setUp()
310
311        # Prepopulate ZODB
312        app = University()
313        self.dc_root = tempfile.mkdtemp()
314        app['datacenter'].setStoragePath(self.dc_root)
315
316        # Prepopulate the ZODB...
317        self.getRootFolder()['app'] = app
318        self.app = self.getRootFolder()['app']
319
320        self.import_sample1_src = os.path.join(
321            os.path.dirname(__file__), 'sample_import.csv')
322
323        setSite(self.app)
324        return
325
326    def tearDown(self):
327        shutil.rmtree(self.dc_root)
328        super(AccessCodeBatchContainerTests, self).tearDown()
329        return
330
331    def test_iface(self):
332        accesscodes = AccessCodeBatchContainer()
333        assert verifyObject(IAccessCodeBatchContainer, accesscodes)
334        assert verifyClass(IAccessCodeBatchContainer, AccessCodeBatchContainer)
335
336    def test_csv_import(self):
337        # Make sure we can reimport sample data from local sample_import.csv
338        batchcontainer = self.app['accesscodes']
339        shutil.copyfile(        # Copy sample to import dir
340            os.path.join(os.path.dirname(__file__), 'sample_import.csv'),
341            os.path.join(batchcontainer._getStoragePath(), 'sample_import.csv')
342            )
343        batchcontainer.reimport('sample_import.csv')
344        batch = batchcontainer.get(u'FOO-1', None)
345        self.assertTrue(batch is not None)
346        keys = [x for x in batch.keys()]
347        self.assertEqual(
348            keys,
349            [u'FOO-1-11111111', u'FOO-1-22222222', u'FOO-1-33333333'])
350
351checker = renormalizing.RENormalizing([
352        (re.compile('[\d]{10}'), '<10-DIGITS>'),
353        ])
354
355def setUp(test):
356    FunctionalTestSetup().setUp()
357
358def tearDown(self, test=None):
359    FunctionalTestSetup().tearDown()
360
361
362
363def test_suite():
364    suite = unittest.TestSuite()
365    for testcase in [
366        AccessCodeHelpersTests,
367        AccessCodeTests,
368        AccessCodeBatchTests,
369        AccessCodeBatchContainerTests,
370        ]:
371        suite.addTests(unittest.TestLoader().loadTestsFromTestCase(testcase))
372    for filename in [
373        #'accesscodes.txt',
374        'browser.txt'
375        ]:
376        path = os.path.join(
377            os.path.dirname(os.path.dirname(__file__)), filename)
378        test = doctest.DocFileSuite(
379            path,
380            module_relative=False,
381            setUp=setUp, tearDown=tearDown,
382            globs = dict(getRootFolder = getRootFolder),
383            optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
384            checker = checker,
385            )
386        test.layer = FunctionalLayer
387        suite.addTest(test)
388    return suite
Note: See TracBrowser for help on using the repository browser.