source: main/waeup.ikoba/trunk/src/waeup/ikoba/doctests/batchprocessing_browser.txt @ 15130

Last change on this file since 15130 was 13806, checked in by Henrik Bettermann, 9 years ago

Add portal maintenance mode.

See r13394, r13396, r13468.

File size: 9.3 KB
Line 
1Batch Processing via Browser
2****************************
3
4Preliminaries:
5
6We define a function that looks up a form with several submit buttons
7for the one with a given value (this functionality is missing in
8zope.testbrowser):
9
10    >>> def lookup_submit_value(name, value, browser):
11    ...   """Find a button with a certain value."""
12    ...   for num in range(0, 100):
13    ...     try:
14    ...       button = browser.getControl(name=name, index=num)
15    ...       if button.value.endswith(value):
16    ...         return button
17    ...     except IndexError:
18    ...       break
19    ...   return None
20
21Create a site:
22
23    >>> from waeup.ikoba.app import Company
24    >>> getRootFolder()['app'] = Company()
25    >>> from zope.component.hooks import setSite
26    >>> setSite(getRootFolder()['app'])
27
28Create a datacenter storage path:
29
30    >>> import os
31    >>> import tempfile
32    >>> dc_path = tempfile.mkdtemp()
33
34Log in:
35
36    >>> from zope.testbrowser.testing import Browser
37    >>> browser = Browser()
38    >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
39    >>> browser.handleErrors = False
40
41Set datacenter path and deselect moving old data:
42
43    >>> browser.open('http://localhost/app')
44    >>> browser.getLink('Data Center').click()
45    >>> browser.getLink('Edit settings').click()
46    >>> browser.getControl(name='newpath').value = dc_path
47    >>> browser.getControl(name='move').value = False
48    >>> browser.getControl(name='save').click()
49
50Set non-usable datacenter path:
51
52    >>> browser.getLink('Edit settings').click()
53    >>> browser.getControl(name='newpath').value = '/'
54    >>> browser.getControl(name='save').click()
55    >>> 'Given storage path cannot be used' in browser.contents
56    True
57    >>> browser.getControl('Back to Data Center').click()
58
59
60Batch processing users
61======================
62
63    >>> browser.open('http://localhost/app/datacenter')
64
65Prepare a CSV file for users:
66
67    >>> open('users.csv', 'wb').write(
68    ... """name,title,public_name,email,phone,roles
69    ... uli,Uli Fouquet,Chief Developer,uli@abc.de,+49-234-567,[]
70    ... henrik,Henrik Bettermann,Admin,henrik@abc.de,+49-234-567,"['waeup.PortalManager', 'waeup.ImportManager']"
71    ... """)
72
73Upload the file:
74
75    >>> import cStringIO
76    >>> browser.getLink('Upload data').click()
77    >>> filecontents = cStringIO.StringIO(
78    ...   open('users.csv', 'rb').read())
79    >>> filewidget = browser.getControl(name='uploadfile:file')
80    >>> filewidget.add_file(filecontents, 'text/plain', 'users.csv')
81    >>> browser.getControl(name='SUBMIT').click()
82
83Step 1: start batch processing:
84
85    >>> browser.getLink('Process data').click()
86    >>> browser.getLink('Switch maintenance mode').click()
87    >>> button = lookup_submit_value(
88    ...   'select', 'users_zope.mgr.csv', browser)
89    >>> button.click()
90
91Step 2: select a processor and mode:
92
93    >>> importerselect = browser.getControl(name='importer')
94    >>> importerselect.getControl('User Processor').selected = True
95    >>> modeselect = browser.getControl(name='mode')
96    >>> modeselect.getControl(value='create').selected = True
97    >>> browser.getControl('Proceed to step 3').click()
98
99Step 3: Fix headerlines
100
101We get informed that there are no problems with the current header:
102
103    >>> print browser.contents
104    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
105    ...
106    Header fields OK
107    ...
108
109The submit button is enabled:
110
111    >>> browser.getControl('Perform import').disabled
112    False
113
114    >>> browser.getControl('Perform import').click()
115
116Step 4: See import results
117
118The import was successful:
119
120    >>> print browser.contents
121    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
122    ...Successfully processed 2 rows...
123    ...Batch processing finished...
124    ...File:...users_zope.mgr.csv...
125
126User henrik has got the global roles:
127
128   >>> henrik = getRootFolder()['app']['users']['henrik']
129   >>> henrik.roles
130   ['waeup.ProductsOfficer', 'waeup.PortalManager', 'waeup.ImportManager']
131
132Pending files
133=============
134
135When an error occurs during an import, two files are generated: a CSV
136file with finished files and a CSV file with pending data. Both are
137stored in the appropriate subdirectories in datacenter. We try to
138create faculties, from which one already exists.
139
140Go to datacenter page:
141
142    >>> browser.open('http://localhost/app/datacenter')
143
144Prepare a CSV file for users:
145
146    >>> open('newusers.csv', 'wb').write(
147    ... """name,title,public_name,email,phone,roles
148    ... isouaba,Issoufou Abba Moussa,Chief Developer,isouaba@abc.de,+49-234-567,[]
149    ... henrik,Henrik Bettermann,Admin,henrik@abc.de,+49-234-567,"['waeup.PortalManager', 'waeup.ImportManager']"
150    ... anne,Anne Palina,,anne@abc.de,+49-234-567,"['waeup.Nonsense']"
151    ... """)
152
153Upload the file:
154
155    >>> import cStringIO
156    >>> browser.getLink('Upload data').click()
157    >>> filecontents = cStringIO.StringIO(
158    ...   open('newusers.csv', 'rb').read())
159    >>> filewidget = browser.getControl(name='uploadfile:file')
160    >>> filewidget.add_file(filecontents, 'text/plain', 'newusers.csv')
161    >>> browser.getControl(name='SUBMIT').click()
162
163Since we now have a user with waeup.ImportManager role, an email has been sent:
164    >>> print browser.contents
165    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
166    ...
167    ...All import managers have been notified by email...
168    ...
169
170Step 1: start batch processing:
171
172    >>> browser.getLink('Process data').click()
173    >>> browser.getLink('Switch maintenance mode').click()
174    >>> button = lookup_submit_value(
175    ...   'select', 'newusers_zope.mgr.csv', browser)
176    >>> button.click()
177
178Step 2: select a processor and mode:
179
180    >>> importerselect = browser.getControl(name='importer')
181    >>> importerselect.getControl('User Processor').selected = True
182    >>> modeselect = browser.getControl(name='mode')
183    >>> modeselect.getControl(value='create').selected = True
184    >>> browser.getControl('Proceed to step 3').click()
185
186Step 3: Fix headerlines
187
188As there should be no problem with the headers, we can immediately
189perfom the import:
190
191    >>> browser.getControl('Perform import').click()
192
193Two lines could not be imported:
194
195    >>> print browser.contents
196    <!DOCTYPE html PUBLIC...
197    ...
198    ...Processing of 2 rows failed...
199    ...Successfully processed 1 rows...
200    ...
201
202Now there are two files as a result in datacenter storage's root and
203``finished`` dirs:
204
205    >>> pending_file = dc_path + '/newusers_zope.mgr.create.pending.csv'
206    >>> print open(pending_file).read()
207    name,roles,title,public_name,phone,email,--ERRORS--
208    henrik,"['waeup.PortalManager', 'waeup.ImportManager']",Henrik Bettermann,Admin,+49-234-567,henrik@abc.de,This object already exists. Skipping.
209    anne,['waeup.Nonsense'],Anne Palina,<IGNORE>,+49-234-567,anne@abc.de,roles: invalid role
210
211    >>> finished_file = dc_path + '/finished/newusers_zope.mgr.create.finished.csv'
212    >>> print open(finished_file).read()
213    name,roles,title,public_name,phone,email
214    isouaba,<IGNORE>,Issoufou Abba Moussa,Chief Developer,+49-234-567,isouaba@abc.de
215
216The finished-file contains the dataset we could import, while the
217pending file contains the dataset that failed, appended by an error
218message.
219
220
221Fixing the pending file
222-----------------------
223
224We 'edit' the pending file by removing anne and replacing henrik by gbenga
225and finish the import this way:
226
227    >>> open(dc_path + '/newusers_zope.mgr.create.pending.csv', 'wb').write(
228    ... """name,title,public_name,email,phone,roles
229    ... gbenga,Jason Bamidele,Chief Developer,gbenga@abc.de,+49-234-567,[]
230    ... """)
231
232Step 1: start batch processing:
233
234    >>> browser.open('http://localhost/app/datacenter')
235    >>> browser.getLink('Process data').click()
236    >>> browser.getLink('Switch maintenance mode').click()
237    >>> button = lookup_submit_value(
238    ...   'select', 'newusers_zope.mgr.create.pending.csv', browser)
239    >>> button.click()
240
241Step 2: select a processor and mode:
242
243    >>> importerselect = browser.getControl(name='importer')
244    >>> importerselect.getControl('User Processor').selected = True
245    >>> modeselect = browser.getControl(name='mode')
246    >>> modeselect.getControl(value='create').selected = True
247    >>> browser.getControl('Proceed to step 3').click()
248
249Step 3/4: Fix headerlines and import:
250
251As there should be no problem with the headers, we can immediately
252perfom the import:
253
254    >>> browser.getControl('Perform import').click()
255
256This time everything should work:
257
258    >>> print browser.contents
259    <!DOCTYPE html PUBLIC...
260    ...
261    ...Successfully processed 1 rows...
262    ...
263
264    >>> sorted(os.listdir(dc_path))
265    ['deleted', 'finished', 'logs', 'unfinished']
266
267    >>> os.listdir(dc_path + '/unfinished')
268    []
269
270    >>> sorted(os.listdir(dc_path + '/finished'))
271    ['newusers_zope.mgr.create.finished.csv', 'newusers_zope.mgr.csv', 'users_zope.mgr.create.finished.csv', 'users_zope.mgr.csv']
272
273Processed (finished) Files
274==========================
275
276    >>> browser.open('http://localhost/app/datacenter/processed')
277    >>> 'download?filename=finished/users_zope.mgr.create.finished.csv' in browser.contents
278    True
279
280Log Files
281=========
282
283    >>> browser.open('http://localhost/app/datacenter/logs')
284    >>> 'datacenter.log' in browser.contents
285    True
286    >>> browser.getControl('Show', index=0).click()
287    >>> browser.getControl('Back', index=0).click()
288    >>> browser.getControl('Back to Data Center').click()
289    >>> 'Storage path:' in browser.contents
290    True
291
292
293Clean up:
294
295    >>> import shutil
296    >>> shutil.rmtree(dc_path)
Note: See TracBrowser for help on using the repository browser.