1 | Browsing Ikoba |
---|
2 | ************* |
---|
3 | |
---|
4 | Here we visit all parts of a Ikoba portal using a browser. |
---|
5 | |
---|
6 | Company |
---|
7 | ======= |
---|
8 | |
---|
9 | We can watch universities in the browser. |
---|
10 | |
---|
11 | We create an company object and put into the ZODB root:: |
---|
12 | |
---|
13 | >>> root = getRootFolder() |
---|
14 | >>> list(root) |
---|
15 | [] |
---|
16 | |
---|
17 | >>> from waeup.ikoba.app import Company |
---|
18 | >>> u = Company() |
---|
19 | >>> root['mycompany'] = u |
---|
20 | >>> list(root) |
---|
21 | [u'mycompany'] |
---|
22 | |
---|
23 | >>> from zope.component.hooks import setSite |
---|
24 | >>> setSite(root['mycompany']) |
---|
25 | |
---|
26 | To make sure, we can 'watch' pages, we first have to initialize out |
---|
27 | test browser:: |
---|
28 | |
---|
29 | >>> from zope.testbrowser.testing import Browser |
---|
30 | >>> browser = Browser() |
---|
31 | |
---|
32 | Let's get the default view of a company:: |
---|
33 | |
---|
34 | >>> browser.open('http://localhost/mycompany') |
---|
35 | >>> print browser.contents |
---|
36 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
37 | ...Welcome to WAeUP.Ikoba... |
---|
38 | ... |
---|
39 | |
---|
40 | We can change to German:: |
---|
41 | >>> browser.getLink('de').click() |
---|
42 | >>> print browser.contents |
---|
43 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
44 | ...Anfragen... |
---|
45 | ... |
---|
46 | |
---|
47 | And then change back to English by clicking on the third link containing 'en' |
---|
48 | behind 'Anfragen' and 'Einloggen':: |
---|
49 | >>> browser.getLink('en', index=2).click() |
---|
50 | >>> print browser.contents |
---|
51 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
52 | ...Enquiries... |
---|
53 | ... |
---|
54 | |
---|
55 | The contact form for anonymous users is called 'Enquiries':: |
---|
56 | |
---|
57 | >>> browser.open('http://localhost/mycompany') |
---|
58 | >>> browser.getLink('Enquiries').click() |
---|
59 | >>> browser.getControl('Send').click() |
---|
60 | >>> print browser.contents |
---|
61 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
62 | ...Required input is missing... |
---|
63 | ... |
---|
64 | |
---|
65 | >>> browser.getControl(name='form.fullname').value = "Bob Tester" |
---|
66 | >>> browser.getControl(name='form.email_from').value = "xx@yy.zz" |
---|
67 | >>> browser.getControl(name='form.body').value = u'test message' |
---|
68 | >>> browser.getControl('Send').click() |
---|
69 | >>> print browser.contents |
---|
70 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
71 | ...Your message has been sent... |
---|
72 | ... |
---|
73 | |
---|
74 | Registered users with an email address can request a password change: |
---|
75 | |
---|
76 | >>> root['mycompany']['users'].addUser('forgetful', 'secret',title='Bob Forgetful', |
---|
77 | ... description='A forgetful user', email='aa@aa.ng') |
---|
78 | >>> browser.open('http://localhost/mycompany/changepw') |
---|
79 | >>> browser.getControl(name="form.email").value = 'aa@aa.ng' |
---|
80 | >>> browser.getControl("Send login credentials").click() |
---|
81 | >>> print browser.contents |
---|
82 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
83 | ...An email with your user name and password has been sent to aa@aa.ng... |
---|
84 | |
---|
85 | Now we login as manager:: |
---|
86 | |
---|
87 | >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw') |
---|
88 | >>> browser.handleErrors = False |
---|
89 | |
---|
90 | We can then get an edit view of the configuration container:: |
---|
91 | |
---|
92 | >>> browser.open('http://localhost/mycompany/configuration') |
---|
93 | >>> print browser.contents |
---|
94 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
95 | ...<form action="http://localhost/mycompany/configuration/@@index" |
---|
96 | ... |
---|
97 | |
---|
98 | The edit form contains the default value for the company name:: |
---|
99 | |
---|
100 | >>> 'Sample Company' in browser.contents |
---|
101 | True |
---|
102 | |
---|
103 | We can perform several actions on the edit form:: |
---|
104 | |
---|
105 | >>> browser.getControl("Save", index=0).click() |
---|
106 | >>> print browser.contents |
---|
107 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
108 | ...Form has been saved... |
---|
109 | ... |
---|
110 | |
---|
111 | >>> browser.open('http://localhost/mycompany/configuration') |
---|
112 | >>> browser.getControl("Update plugins").click() |
---|
113 | >>> print browser.contents |
---|
114 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
115 | ...Plugins were updated. See log file for details... |
---|
116 | ... |
---|
117 | |
---|
118 | The default frontpage HTML has been saved in a dictionary |
---|
119 | and is properly rendered on the frontpage of the portal: |
---|
120 | |
---|
121 | >>> browser.open('http://localhost/mycompany') |
---|
122 | >>> print browser.contents |
---|
123 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
124 | ...<h1>Welcome to WAeUP.Ikoba...</h1> |
---|
125 | ... |
---|
126 | |
---|
127 | The German part is really not being rendered: |
---|
128 | |
---|
129 | >>> 'Willkommen' in browser.contents |
---|
130 | False |
---|
131 | |
---|
132 | |
---|
133 | If we change to German so that the German part of frontpage.rst is rendered: |
---|
134 | |
---|
135 | >>> browser.open('http://localhost/mycompany//@@change_language?lang=de') |
---|
136 | >>> print browser.contents |
---|
137 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
138 | ...<h1>Willkommen auf WAeUP.Ikoba...</h1> |
---|
139 | ... |
---|
140 | |
---|
141 | The English part is really not being rendered: |
---|
142 | |
---|
143 | >>> 'Welcome' in browser.contents |
---|
144 | False |
---|
145 | |
---|
146 | Switch back to English: |
---|
147 | |
---|
148 | >>> browser.open('http://localhost/mycompany//@@change_language?lang=en') |
---|
149 | |
---|
150 | |
---|
151 | Officers |
---|
152 | ======== |
---|
153 | |
---|
154 | >>> browser.open('http://localhost/mycompany') |
---|
155 | >>> browser.getLink('Officers').click() |
---|
156 | >>> print browser.contents |
---|
157 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
158 | ...Officers... |
---|
159 | ... |
---|
160 | |
---|
161 | We can add users: |
---|
162 | |
---|
163 | >>> browser.getLink("Add user").click() |
---|
164 | >>> browser.getControl(name="form.name").value = 'bob' |
---|
165 | >>> browser.getControl(name="form.title").value = 'Bob The User' |
---|
166 | >>> browser.getControl(name="password").value = 'secret' |
---|
167 | >>> browser.getControl(name="control_password").value = 'secret' |
---|
168 | >>> browser.getControl(name="form.email").value = 'xx@yy.zz' |
---|
169 | >>> browser.getControl(name="form.phone.country").value = ['+234'] |
---|
170 | >>> browser.getControl(name="form.phone.area").value = '123' |
---|
171 | >>> browser.getControl(name="form.phone.ext").value = '45678' |
---|
172 | >>> browser.getControl("Add user").click() |
---|
173 | >>> print browser.contents |
---|
174 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
175 | ...<td>bob</td> |
---|
176 | ... |
---|
177 | |
---|
178 | We can edit user bob: |
---|
179 | |
---|
180 | >>> browser.getControl("Manage", index=0).click() |
---|
181 | >>> browser.getControl("Save", index=0).click() |
---|
182 | >>> browser.getControl("Cancel", index=0).click() |
---|
183 | |
---|
184 | We can add site roles which are then displayed on the user container page. |
---|
185 | Since the test browser does not use javascript, we have to add site roles |
---|
186 | manually by setting the roles attribute: |
---|
187 | |
---|
188 | Since JS is not supported by the test browser, the default role has been removed |
---|
189 | when clicking the Save button. |
---|
190 | |
---|
191 | >>> print root['mycompany']['users']['bob'].roles |
---|
192 | [] |
---|
193 | >>> root['mycompany']['users']['bob'].roles = ['waeup.UsersManager'] |
---|
194 | >>> print root['mycompany']['users']['bob'].roles |
---|
195 | ['waeup.UsersManager'] |
---|
196 | >>> browser.open('http://localhost/mycompany/users') |
---|
197 | >>> print browser.contents |
---|
198 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
199 | ...<td nowrap>Users Manager <br /></td> |
---|
200 | ... |
---|
201 | |
---|
202 | Users can't be added twice: |
---|
203 | |
---|
204 | >>> browser.open('http://localhost/mycompany/users/add') |
---|
205 | >>> browser.getControl(name="form.name").value = 'bob' |
---|
206 | >>> browser.getControl(name="form.title").value = 'Bob The User' |
---|
207 | >>> browser.getControl(name="password").value = 'secret' |
---|
208 | >>> browser.getControl(name="control_password").value = 'secret' |
---|
209 | >>> browser.getControl(name="form.email").value = 'xx@yy.zz' |
---|
210 | >>> browser.getControl(name="form.phone.country").value = ['+234'] |
---|
211 | >>> browser.getControl(name="form.phone.area").value = '123' |
---|
212 | >>> browser.getControl(name="form.phone.ext").value = '45678' |
---|
213 | >>> browser.getControl("Add user").click() |
---|
214 | >>> 'The userid chosen already exists' in browser.contents |
---|
215 | True |
---|
216 | |
---|
217 | Users can be deleted: |
---|
218 | |
---|
219 | >>> browser.open('http://localhost/mycompany/users') |
---|
220 | >>> browser.getControl("Remove", index=0).click() |
---|
221 | >>> 'User account bob successfully deleted' in browser.contents |
---|
222 | True |
---|
223 | |
---|
224 | |
---|
225 | |
---|
226 | Contact Form |
---|
227 | ============ |
---|
228 | |
---|
229 | Let's enter the contact form:: |
---|
230 | |
---|
231 | >>> browser.open('http://localhost/mycompany/contactadmin') |
---|
232 | >>> print browser.contents |
---|
233 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
234 | ...Contact |
---|
235 | ... |
---|
236 | |
---|
237 | We fill the form (this will send a real message to |
---|
238 | contact@waeup.org):: |
---|
239 | |
---|
240 | >>> browser.open('http://localhost/mycompany/contactadmin') |
---|
241 | >>> browser.getControl(name='form.body').value = "test message" |
---|
242 | >>> browser.getControl('Send').click() |
---|
243 | >>> print browser.contents |
---|
244 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
245 | ...Your message has been sent... |
---|
246 | ... |
---|
247 | |
---|
248 | If this test fails, chances are, that the local machine has no SMTP |
---|
249 | server installed. |
---|
250 | |
---|
251 | |
---|
252 | Data Center |
---|
253 | =========== |
---|
254 | |
---|
255 | The data center helps us uploading files for later import or similar. |
---|
256 | |
---|
257 | >>> browser.open('http://localhost/mycompany') |
---|
258 | >>> browser.getLink('Data Center').click() |
---|
259 | |
---|
260 | Setting the file path |
---|
261 | --------------------- |
---|
262 | |
---|
263 | A datacenter stores files in a path in filesystem. By default this is |
---|
264 | a directory in the sources: |
---|
265 | |
---|
266 | >>> print browser.contents |
---|
267 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
---|
268 | ... |
---|
269 | <b>Storage path:</b> <span>.../parts/test/datacenter</span> |
---|
270 | ... |
---|
271 | |
---|
272 | Going to 'Settings` we can change the path: |
---|
273 | |
---|
274 | >>> browser.getLink('Edit settings').click() |
---|
275 | >>> pathsetting = browser.getControl(name='newpath') |
---|
276 | |
---|
277 | We create a directory and set it as our upload path: |
---|
278 | |
---|
279 | >>> import os |
---|
280 | >>> cwd = os.getcwd() |
---|
281 | >>> uploadpath = os.path.join(cwd, 'testfiles') |
---|
282 | >>> os.mkdir(uploadpath) |
---|
283 | >>> pathsetting.value = uploadpath |
---|
284 | |
---|
285 | And submit the form: |
---|
286 | |
---|
287 | >>> browser.getControl(name='save').click() |
---|
288 | |
---|
289 | We clean up the set directory path, as there might be some files be |
---|
290 | copied some files from installation: |
---|
291 | |
---|
292 | >>> files = os.listdir(uploadpath) |
---|
293 | >>> for filename in files: |
---|
294 | ... if os.path.isdir(os.path.join(uploadpath, filename)): |
---|
295 | ... continue |
---|
296 | ... os.unlink(os.path.join(uploadpath, filename)) |
---|
297 | |
---|
298 | We also remove any existing 'accesscodes' subdir: |
---|
299 | |
---|
300 | >>> import shutil |
---|
301 | >>> for filename in files: |
---|
302 | ... if not os.path.isdir(os.path.join(uploadpath, filename)): |
---|
303 | ... continue |
---|
304 | ... if filename != 'accesscodes': |
---|
305 | ... continue |
---|
306 | ... shutil.rmtree(os.path.join(uploadpath, filename)) |
---|
307 | |
---|
308 | The new upload directory is now empty, except from the logs and other |
---|
309 | standard dirs, which are created automatically: |
---|
310 | |
---|
311 | >>> sorted(os.listdir(uploadpath)) |
---|
312 | ['deleted', 'finished', 'logs', 'unfinished'] |
---|
313 | |
---|
314 | |
---|
315 | Uploading files |
---|
316 | --------------- |
---|
317 | |
---|
318 | Now we can upload files. Most interesting files might be CSV files, |
---|
319 | that can be imported lateron. We create a CSV file containing faculty |
---|
320 | descriptions: |
---|
321 | |
---|
322 | >>> open('faculties.csv', 'wb').write( |
---|
323 | ... """code,title,title_prefix |
---|
324 | ... FA,Arts,faculty |
---|
325 | ... FS,Sciences,faculty |
---|
326 | ... """) |
---|
327 | |
---|
328 | Now we can upload this file. To do this, we first go to the upload |
---|
329 | page: |
---|
330 | |
---|
331 | >>> browser.getLink('Upload data').click() |
---|
332 | |
---|
333 | and enter the appropriate data in the form: |
---|
334 | |
---|
335 | >>> filewidget = browser.getControl(name='uploadfile:file') |
---|
336 | >>> filewidget |
---|
337 | <Control name='uploadfile:file' type='file'> |
---|
338 | |
---|
339 | A sidenote for developers: by marking the filewidget with the |
---|
340 | ``:file`` extension, we tell Zope to handle this field as a file |
---|
341 | widget. |
---|
342 | |
---|
343 | >>> import cStringIO |
---|
344 | >>> filecontents = cStringIO.StringIO( |
---|
345 | ... open('faculties.csv', 'rb').read()) |
---|
346 | >>> filewidget.add_file(filecontents, 'text/plain', 'myfaculties.csv') |
---|
347 | |
---|
348 | >>> browser.getControl(name='SUBMIT').click() |
---|
349 | |
---|
350 | The file was indeed uploaded, with the current userid inserted: |
---|
351 | |
---|
352 | >>> sorted(os.listdir(uploadpath)) |
---|
353 | ['deleted', 'finished', 'logs', 'myfaculties_zope.mgr.csv', 'unfinished'] |
---|
354 | |
---|
355 | |
---|
356 | |
---|
357 | Importing a CSV file |
---|
358 | -------------------- |
---|
359 | |
---|
360 | The import of CSV files is described in batchprocessing.txt. |
---|
361 | |
---|
362 | |
---|
363 | Clean up: |
---|
364 | |
---|
365 | >>> import os |
---|
366 | >>> import shutil |
---|
367 | >>> shutil.rmtree(uploadpath) |
---|
368 | |
---|