source: main/waeup.sirp/trunk/src/waeup/sirp/accesscodes/browser.txt @ 6438

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

Support batch-local counters for used/disabled pins. This time we only set a simple attribute and remove the enable(), disable(), ... methods that have no purpose any more.

File size: 9.7 KB
Line 
1:mod:`waeup.sirp.accesscodes.browser` -- UI components for access-codes
2***********************************************************************
3
4.. module:: waeup.sirp.accesscodes.browser
5
6Here we visit the access-code related parts of a WAeUP SIRP site using
7a virtual browser.
8
9:NOTTest-Layer: functional
10
11Preliminaries
12=============
13
14Before we can do anything, we have to create a university site:
15
16    >>> from zope.testbrowser.testing import Browser
17    >>> browser = Browser()
18    >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
19    >>> browser.handleErrors = False
20    >>> root = getRootFolder()
21
22    >>> from waeup.sirp.app import University
23    >>> u = University()
24    >>> root['myuniversity'] = u
25
26We set a new datacenter storage path:
27
28  >>> import os
29  >>> browser.open('http://localhost/myuniversity')
30  >>> browser.getLink('Data Center').click()
31  >>> browser.getLink('Edit settings').click()
32  >>> pathsetting = browser.getControl(name='newpath')
33
34  >>> cwd = os.getcwd()
35  >>> uploadpath = os.path.join(cwd, 'ac_testfiles')
36  >>> os.mkdir(uploadpath)
37  >>> pathsetting.value = uploadpath
38  >>> browser.getControl(name='save').click()
39
40We remove any existing 'accesscodes' dir from datacenter dir:
41
42  >>> import shutil
43  >>> if os.path.exists(os.path.join(uploadpath, 'accesscodes')):
44  ...   shutil.rmtree(os.path.join(uploadpath, 'accesscodes'))
45
46
47Access-code management screen
48=============================
49
50For users that have the right to manage access-code related stuff, the
51home page of a `University` instance provides a link to the
52access-code management screen. In the beginning, there are naturally
53no batches available:
54
55    >>> browser.open('http://localhost/myuniversity')
56    >>> browser.getLink('Access Codes').click()
57    >>> print browser.contents
58    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
59    ...
60    <h2>Access Code Batches</h2>
61    ...
62    ... The following batches are available:
63    ...No batches yet...
64    ...
65
66Adding batches
67==============
68
69We can add a batch of access-codes using a button displayed in the
70action bar:
71
72    >>> browser.getLink('Add Scratch Card Batch').click()
73
74The add screen shows a form where we have to enter a prefix, the
75number of access codes to be generated and the costs for each card.
76
77    >>> browser.getControl(name='form.prefix').value = 'APP'
78    >>> browser.getControl(name='form.entry_num').value = '5'
79    >>> browser.getControl(name='form.cost').value = '12.12'
80
81If we click 'cancel' afterwards, the whole process will be cancelled
82and we'll be redirected to the management screen:
83
84    >>> browser.getControl('Cancel').click()
85    >>> browser.url
86    'http://localhost/myuniversity/accesscodes'
87
88    >>> 'Batch creation cancelled' in browser.contents
89    True
90
91Now let's try again and this time we finish the procedure by clicking
92'Create batch' in the form:
93
94    >>> browser.getLink('Add Scratch Card Batch').click()
95    >>> browser.getControl(name='form.prefix').value = 'APP'
96    >>> browser.getControl(name='form.entry_num').value = '5'
97    >>> browser.getControl(name='form.cost').value = '12.12'
98    >>> browser.getControl('Create batch').click()
99
100We're also redirected to the management screen, with a notice about
101the freshly created batch:
102
103    >>> print browser.contents
104    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
105    ...
106    <h2>Access Code Batches</h2>
107    ...
108    ... The following batches are available:
109    ...APP
110    ...-
111    ...1
112    ...
113    ...5
114    .../
115    ...0
116    ...
117    ...12.12...
118    ...zope.mgr...
119    ...
120
121which means: there exists a batch named ``APP-1`` with 5 entries of
122which 0 have been devalidated, each one costs ``12.12`` and the batch
123was created by ``zope.mgr``.
124
125We create a second batch to see whether searching and related stuff
126works:
127
128    >>> browser.getLink('Add Scratch Card Batch').click()
129    >>> browser.getControl(name='form.prefix').value = 'APP'
130    >>> browser.getControl(name='form.entry_num').value = '5'
131    >>> browser.getControl(name='form.cost').value = '10.12'
132    >>> browser.getControl('Create batch').click()
133
134And a third one that can be deleted afterwards:
135
136    >>> browser.getLink('Add Scratch Card Batch').click()
137    >>> browser.getControl(name='form.prefix').value = 'BLA'
138    >>> browser.getControl(name='form.entry_num').value = '3'
139    >>> browser.getControl(name='form.cost').value = '19.12'
140    >>> browser.getControl('Create batch').click()
141
142
143Creating Archive Files
144======================
145
146Once a batch is created, we can archive it. To do so we have to tick
147the respective checkbox and click on 'Archive':
148
149    >>> ctrl = browser.getControl(name='batches')
150    >>> ctrl.getControl(value='APP-2').selected = True
151    >>> browser.getControl(name='archive').click()
152    >>> print browser.contents
153    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
154    ...
155    <li ...>Archived APP-2 (APP-2_archive-...-zope.mgr.csv)</li>
156    ...
157
158If we do not select a batch and try to archive or delete, the system
159will complain:
160
161    >>> browser.getControl(name='archive').click()
162    >>> print browser.contents
163    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
164    ...
165    <li ...>No batch selected.</li>
166    ...
167
168Deleting Batches
169================
170
171We can delete batches. They are automatically archived when doing so:
172
173    >>> ctrl = browser.getControl(name='batches')
174    >>> ctrl.getControl(value='BLA-1').selected = True
175    >>> browser.getControl('Archive and Delete').click()
176    >>> print browser.contents
177    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
178    ...Archived BLA-1 (BLA-1_archive-...-zope.mgr.csv)...
179    ...Deleted batch BLA-1...
180    ...
181
182
183Reimporting Batches
184===================
185
186We can reimport batches using the log files written when a batch was
187created before. So one can reimport the freshly deleted BLA-1
188batch.
189
190To do so we must copy the logfile into the ``imports`` dir of
191accesscodes inside the university's datacenter storage. Otherwisae the
192list of importable files is empty:
193
194    >>> browser.getLink('Reimport Scratch Card Batch').click()
195    >>> print browser.contents
196    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
197    ...
198    ...No import batches available...
199    ...
200
201We can cancel that operation:
202
203    >>> browser.getControl('Cancel').click()
204
205We copy the ``BLA-1`` batch logfile over to the ``imports`` directory:
206
207    >>> ac_storage = os.path.join(uploadpath, 'accesscodes')
208    >>> logfile2 = os.path.join(ac_storage,
209    ...                         sorted(os.listdir(ac_storage))[-3])
210    >>> filename = os.path.basename(logfile2)
211    >>> filename
212    'BLA-1-...-zope.mgr.csv'
213
214    >>> import shutil
215    >>> import_path = os.path.join(ac_storage, 'imports')
216    >>> shutil.copy(logfile2, import_path)
217
218Now the file will be presented as import source:
219
220    >>> browser.getLink('Reimport Scratch Card Batch').click()
221    >>> filename in browser.contents
222    True
223
224If we do not tick a filename to import and click 'Reimport', we will
225be warned:
226
227    >>> browser.getControl('Reimport').click()
228    >>> print browser.contents
229    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
230    ...No file chosen. Action cancelled...
231
232Now let's really reimport the batch:
233
234    >>> browser.getLink('Reimport Scratch Card Batch').click()
235    >>> ctrl = browser.getControl(name='filenames')
236    >>> ctrl.getControl(value=filename).selected = True
237    >>> browser.getControl('Reimport').click()
238
239The batch does exist now again:
240
241    >>> print browser.contents
242    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
243    ...Successfully reimported: BLA-1-...-zope.mgr.csv...
244    ...
245
246If we try to reimport an existing batch, that won't work:
247
248    >>> browser.getLink('Reimport Scratch Card Batch').click()
249    >>> ctrl = browser.getControl(name='filenames')
250    >>> ctrl.getControl(value=filename).selected = True
251    >>> browser.getControl('Reimport').click()
252    >>> print browser.contents
253    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
254    ...This batch already exists: BLA-1-...-zope.mgr.csv...
255    ...
256
257
258Log- and Archive Files
259======================
260
261We store log- and archive-files inside the storage managed by the
262local datacenter. Access-code related files are placed inside an
263``accesscode`` subdir:
264
265    >>> ac_storage = os.path.join(uploadpath, 'accesscodes')
266
267Log files for access-code batches
268---------------------------------
269
270Whenever a batch is created, there is also a log file with all entries
271created:
272
273    >>> sorted(os.listdir(ac_storage))
274    ['APP-1-...-zope.mgr.csv', 'APP-2-...-zope.mgr.csv', ...]
275
276Each logfile name contains the prefix, batch number, date of creation
277and userid of creator.
278
279    >>> logfile1 = os.path.join(ac_storage,
280    ...                         sorted(os.listdir(ac_storage))[0])
281    >>> print open(logfile1, 'rb').read()
282    "serial","ac","cost"
283    "APP","1","12.12"
284    "0","APP-1-<10-DIGITS>"
285    "1","APP-1-<10-DIGITS>"
286    "2","APP-1-<10-DIGITS>"
287    "3","APP-1-<10-DIGITS>"
288    "4","APP-1-<10-DIGITS>"
289
290
291
292Archive files
293-------------
294
295We created an archive file above. An archive file name consists of the
296batch prefix, batch number, the string ``_archive``, creation datetime of
297the archive file and userid of batch creator:
298
299    >>> sorted(os.listdir(ac_storage))
300    [..., 'BLA-1_archive-...-zope.mgr.csv', 'imports']
301
302Archive files eventually also contain infos about invalidation dates
303and have a slightly different format therefore.
304
305    >>> archive_file = os.path.join(ac_storage,
306    ...                             sorted(os.listdir(ac_storage))[-2])
307    >>> print open(archive_file, 'rb').read()
308    "prefix","serial","ac","student","date"
309    "BLA","19.12","1","3"
310    "BLA","0","BLA-1-<10-DIGITS>","","..."
311    "BLA","1","BLA-1-<10-DIGITS>","",""
312    "BLA","2","BLA-1-<10-DIGITS>","",""
313
314Clean up:
315
316    >>> shutil.rmtree(uploadpath)
Note: See TracBrowser for help on using the repository browser.