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

Last change on this file since 6092 was 5423, checked in by uli, 14 years ago

Fix tests.

File size: 9.9 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:Test-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.batch_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.batch_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.batch_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.batch_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
142We also invalidate one entry:
143
144    >>> batch = getRootFolder()['myuniversity']['accesscodes']['BLA-1']
145    >>> ac = list(batch.entries())[0]
146    >>> batch.invalidate(ac.representation)
147
148Creating Archive Files
149======================
150
151Once a batch is created, we can archive it. To do so we have to tick
152the respective checkbox and click on 'Archive':
153
154    >>> ctrl = browser.getControl(name='batches')
155    >>> ctrl.getControl(value='APP-2').selected = True
156    >>> browser.getControl(name='archive').click()
157    >>> print browser.contents
158    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
159    ...
160    <li ...>Archived APP-2 (APP-2_archive-...-zope.mgr.csv)</li>
161    ...
162
163If we do not select a batch and try to archive or delete, the system
164will complain:
165
166    >>> browser.getControl(name='archive').click()
167    >>> print browser.contents
168    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
169    ...
170    <li ...>No batch selected.</li>
171    ...
172
173Deleting Batches
174================
175
176We can delete batches. They are automatically archived when doing so:
177
178    >>> ctrl = browser.getControl(name='batches')
179    >>> ctrl.getControl(value='BLA-1').selected = True
180    >>> browser.getControl('Archive and Delete').click()
181    >>> print browser.contents
182    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
183    ...Archived BLA-1 (BLA-1_archive-...-zope.mgr.csv)...
184    ...Deleted batch BLA-1...
185    ...
186
187
188Reimporting Batches
189===================
190
191We can reimport batches using the log files written when a batch was
192created before. So one can reimport the freshly deleted BLA-1
193batch.
194
195To do so we must copy the logfile into the ``imports`` dir of
196accesscodes inside the university's datacenter storage. Otherwisae the
197list of importable files is empty:
198
199    >>> browser.getLink('Reimport Scratch Card Batch').click()
200    >>> print browser.contents
201    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
202    ...
203    ...No import batches available...
204    ...
205
206We can cancel that operation:
207
208    >>> browser.getControl('Cancel').click()
209
210We copy the ``BLA-1`` batch logfile over to the ``imports`` directory:
211
212    >>> ac_storage = os.path.join(uploadpath, 'accesscodes')
213    >>> logfile2 = os.path.join(ac_storage,
214    ...                         sorted(os.listdir(ac_storage))[-3])
215    >>> filename = os.path.basename(logfile2)
216    >>> filename
217    'BLA-1-...-zope.mgr.csv'
218
219    >>> import shutil
220    >>> import_path = os.path.join(ac_storage, 'imports')
221    >>> shutil.copy(logfile2, import_path)
222
223Now the file will be presented as import source:
224
225    >>> browser.getLink('Reimport Scratch Card Batch').click()
226    >>> filename in browser.contents
227    True
228
229If we do not tick a filename to import and click 'Reimport', we will
230be warned:
231
232    >>> browser.getControl('Reimport').click()
233    >>> print browser.contents
234    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
235    ...No file chosen. Action cancelled...
236
237Now let's really reimport the batch:
238
239    >>> browser.getLink('Reimport Scratch Card Batch').click()
240    >>> ctrl = browser.getControl(name='filenames')
241    >>> ctrl.getControl(value=filename).selected = True
242    >>> browser.getControl('Reimport').click()
243
244The batch does exist now again:
245
246    >>> print browser.contents
247    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
248    ...Successfully reimported: BLA-1-...-zope.mgr.csv...
249    ...
250
251If we try to reimport an existing batch, that won't work:
252
253    >>> browser.getLink('Reimport Scratch Card Batch').click()
254    >>> ctrl = browser.getControl(name='filenames')
255    >>> ctrl.getControl(value=filename).selected = True
256    >>> browser.getControl('Reimport').click()
257    >>> print browser.contents
258    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
259    ...This batch already exists: BLA-1-...-zope.mgr.csv...
260    ...
261
262
263Log- and Archive Files
264======================
265
266We store log- and archive-files inside the storage managed by the
267local datacenter. Access-code related files are placed inside an
268``accesscode`` subdir:
269
270    >>> ac_storage = os.path.join(uploadpath, 'accesscodes')
271
272Log files for access-code batches
273---------------------------------
274
275Whenever a batch is created, there is also a log file with all entries
276created:
277
278    >>> sorted(os.listdir(ac_storage))
279    ['APP-1-...-zope.mgr.csv', 'APP-2-...-zope.mgr.csv', ...]
280
281Each logfile name contains the prefix, batch number, date of creation
282and userid of creator.
283
284    >>> logfile1 = os.path.join(ac_storage,
285    ...                         sorted(os.listdir(ac_storage))[0])
286    >>> print open(logfile1, 'rb').read()
287    "serial","ac","cost"
288    "APP","1","12.12"
289    "0","APP-1-<10-DIGITS>"
290    "1","APP-1-<10-DIGITS>"
291    "2","APP-1-<10-DIGITS>"
292    "3","APP-1-<10-DIGITS>"
293    "4","APP-1-<10-DIGITS>"
294
295
296
297Archive files
298-------------
299
300We created an archive file above. An archive file name consists of the
301batch prefix, batch number, the string ``_archive``, creation datetime of
302the archive file and userid of batch creator:
303
304    >>> sorted(os.listdir(ac_storage))
305    [..., 'BLA-1_archive-...-zope.mgr.csv', 'imports']
306
307Archive files eventually also contain infos about invalidation dates
308and have a slightly different format therefore.
309
310    >>> archive_file = os.path.join(ac_storage,
311    ...                             sorted(os.listdir(ac_storage))[-2])
312    >>> print open(archive_file, 'rb').read()
313    "prefix","serial","ac","student","date"
314    "BLA","19.12","1","3"
315    "BLA","0","BLA-1-<10-DIGITS>","","..."
316    "BLA","1","BLA-1-<10-DIGITS>","",""
317    "BLA","2","BLA-1-<10-DIGITS>","",""
318
319Clean up:
320
321    >>> shutil.rmtree(uploadpath)
Note: See TracBrowser for help on using the repository browser.