source: main/waeup.kofa/trunk/src/waeup/kofa/browser/browser.txt @ 9169

Last change on this file since 9169 was 9024, checked in by Henrik Bettermann, 12 years ago

Rename buttons in datacenter.

Provide a table of available processors with available fields on DatacenterUploadPage? (work in progress).

File size: 43.0 KB
Line 
1Browsing Kofa
2*************
3
4Here we visit all parts of a Kofa portal using a browser.
5
6University
7==========
8
9We can watch universities in the browser.
10
11We create an university object and put into the ZODB root::
12
13  >>> root = getRootFolder()
14  >>> list(root)
15  []
16
17  >>> from waeup.kofa.app import University
18  >>> u = University()
19  >>> root['myuniversity'] = u
20  >>> list(root)
21  [u'myuniversity']
22
23  >>> from zope.component.hooks import setSite
24  >>> setSite(root['myuniversity'])
25
26To make sure, we can 'watch' pages, we first have to initialize out
27test browser::
28
29  >>> from zope.testbrowser.testing import Browser
30  >>> browser = Browser()
31
32Let's get the default view of a university and see if the
33favicon is properly referenced::
34
35  >>> browser.open('http://localhost/myuniversity')
36  >>> print browser.contents
37  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
38  ...href="http://localhost/myuniversity/@@/waeup_kofa/favicon.ico"
39  ...Welcome to WAeUP.Kofa...
40  ...
41
42We can change to German::
43  >>> browser.getLink('de').click()
44  >>> print browser.contents
45  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
46  ...Anfragen...
47  ...
48
49And then change back to English by clicking on the third link containing 'en'
50behind 'Anfragen' and 'Einloggen'::
51  >>> browser.getLink('en', index=2).click()
52  >>> print browser.contents
53  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
54  ...Enquiries...
55  ...
56
57The contact form for anonymous users is called 'Enquiries'::
58
59  >>> browser.open('http://localhost/myuniversity')
60  >>> browser.getLink('Enquiries').click()
61  >>> browser.getControl('Send').click()
62  >>> print browser.contents
63  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
64  ...Required input is missing...
65  ...
66
67  >>> browser.getControl(name='form.fullname').value = "Bob Tester"
68  >>> browser.getControl(name='form.email_from').value = "xx@yy.zz"
69  >>> browser.getControl(name='form.body').value = u'test message'
70  >>> browser.getControl('Send').click()
71  >>> print browser.contents
72  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
73  ...Your message has been sent...
74  ...
75
76Registered users with an email address can request a password change:
77
78  >>> root['myuniversity']['users'].addUser('forgetful', 'secret',title='Bob Forgetful',
79  ...                               description='A forgetful user', email='aa@aa.ng')
80  >>> browser.open('http://localhost/myuniversity/changepw')
81  >>> browser.getControl(name="form.identifier").value = 'forgetful'
82  >>> browser.getControl(name="form.email").value = 'aa@aa.ng'
83  >>> browser.getControl("Get login credentials").click()
84  >>> print browser.contents
85  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
86  ...An email with your user name and password has been sent to aa@aa.ng...
87
88Now we login as manager::
89
90  >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
91  >>> browser.handleErrors = False
92
93We can then get an edit view of the configuration container::
94
95  >>> browser.open('http://localhost/myuniversity/configuration')
96  >>> print browser.contents
97  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
98  ...<form action="http://localhost/myuniversity/configuration/@@index"
99  ...
100
101The edit form contains the default value for the university name::
102
103  >>> 'Sample University' in browser.contents
104  True
105
106The edit form contains the default value for the portal skin::
107
108  >>> 'waeup-base.css' in browser.contents
109  True
110
111We can perform several actions on the edit form::
112
113  >>> browser.getControl("Save", index=0).click()
114  >>> print browser.contents
115  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
116  ...Form has been saved...
117  ...
118
119  >>> browser.open('http://localhost/myuniversity/configuration')
120  >>> browser.getControl("Update plugins").click()
121  >>> print browser.contents
122  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
123  ...Plugins were updated. See log file for details...
124  ...
125
126The default frontpage HTML has been saved in a dictionary
127and is properly rendered on the frontpage of the portal:
128
129  >>> browser.open('http://localhost/myuniversity')
130  >>> print browser.contents
131  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
132  ...<h1>Welcome to WAeUP.Kofa...</h1>
133  ...
134
135The German part is really not being rendered:
136
137  >>> 'Willkommen' in browser.contents
138  False
139
140
141If we change to German so that the German part of frontpage.rst is rendered:
142
143  >>> browser.open('http://localhost/myuniversity//@@change_language?lang=de')
144  >>> print browser.contents
145  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
146  ...<h1>Willkommen auf WAeUP.Kofa...</h1>
147  ...
148
149The English part is really not being rendered:
150
151  >>> 'Welcome' in browser.contents
152  False
153
154Switch back to English:
155
156  >>> browser.open('http://localhost/myuniversity//@@change_language?lang=en')
157
158We can export a university as XML::
159
160  >>> browser.open('http://localhost/myuniversity/export.xml')
161  >>> print browser.contents
162  <?xml version="1.0" encoding="utf-8" ?>
163  <pickle>
164  ...
165  </pickle>
166
167  >>> print browser.headers
168  Status: 200 Ok
169  Content-Length: ...
170  Content-Type: text/xml; charset=UTF-8
171  X-Powered-By: Zope (www.zope.org), Python (www.python.org)
172
173
174Portal Users
175============
176
177  >>> browser.open('http://localhost/myuniversity')
178  >>> browser.getLink('Portal Users').click()
179  >>> print browser.contents
180  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
181  ...Portal Users...
182  ...
183
184We can add users:
185
186  >>> browser.getLink("Add user").click()
187  >>> browser.getControl(name="form.name").value = 'bob'
188  >>> browser.getControl(name="form.title").value = 'Bob The User'
189  >>> browser.getControl(name="password").value = 'secret'
190  >>> browser.getControl(name="control_password").value = 'secret'
191  >>> browser.getControl(name="form.email").value = 'xx@yy.zz'
192  >>> browser.getControl(name="form.phone.country").value = ['+234']
193  >>> browser.getControl(name="form.phone.area").value = '123'
194  >>> browser.getControl(name="form.phone.ext").value = '45678'
195  >>> browser.getControl("Add user").click()
196  >>> print browser.contents
197  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
198  ...<td>bob</td>
199  ...
200
201We can edit user bob:
202
203  >>> browser.getControl("Manage", index=0).click()
204  >>> browser.getControl("Save", index=0).click()
205  >>> browser.getControl("Cancel", index=0).click()
206
207We can add site roles which are then displayed on the user container page.
208Since the test browser does not use javascript, we have to add site roles
209manually by setting the roles attribute:
210
211  >>> print root['myuniversity']['users']['bob'].roles
212  []
213  >>> root['myuniversity']['users']['bob'].roles = ['waeup.ApplicationsOfficer']
214  >>> print root['myuniversity']['users']['bob'].roles
215  ['waeup.ApplicationsOfficer']
216  >>> browser.open('http://localhost/myuniversity/users')
217  >>> print browser.contents
218  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
219  ...<td>Applications Officer <br /></td>
220  ...
221
222Users can't be added twice:
223
224  >>> browser.open('http://localhost/myuniversity/users/add')
225  >>> browser.getControl(name="form.name").value = 'bob'
226  >>> browser.getControl(name="form.title").value = 'Bob The User'
227  >>> browser.getControl(name="password").value = 'secret'
228  >>> browser.getControl(name="control_password").value = 'secret'
229  >>> browser.getControl(name="form.email").value = 'xx@yy.zz'
230  >>> browser.getControl(name="form.phone.country").value = ['+234']
231  >>> browser.getControl(name="form.phone.area").value = '123'
232  >>> browser.getControl(name="form.phone.ext").value = '45678'
233  >>> browser.getControl("Add user").click()
234  >>> 'The userid chosen already exists' in browser.contents
235  True
236
237Users can be deleted:
238
239  >>> browser.open('http://localhost/myuniversity/users')
240  >>> browser.getControl("Remove", index=0).click()
241  >>> 'User account bob successfully deleted' in browser.contents
242  True
243
244
245
246Contact Form
247============
248
249Let's enter the contact form::
250
251  >>> browser.open('http://localhost/myuniversity/contactadmin')
252  >>> print browser.contents
253  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
254  ...Contact
255  ...
256
257We fill the form  (this will send a real message to
258contact@waeup.org)::
259
260  >>> browser.open('http://localhost/myuniversity/contactadmin')
261  >>> browser.getControl(name='form.body').value = "test message"
262  >>> browser.getControl('Send').click()
263  >>> print browser.contents
264  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
265  ...Your message has been sent...
266  ...
267
268If this test fails, chances are, that the local machine has no SMTP
269server installed.
270
271
272
273Faculties
274=========
275
276Faculties are stored in a special container of `IUniversity`
277instances. The container is called ``faculties`` and provides an
278add-form to add new faculties::
279
280  >>> browser.open('http://localhost/myuniversity/faculties/manage')
281  >>> browser.getControl('Add faculty').click()
282  >>> print browser.contents
283  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
284  ...*...
285  ...<span>Name of faculty</span>:
286  ...
287  >>> browser.getControl('Cancel').click()
288  >>> browser.open('http://localhost/myuniversity/faculties/add')
289
290We fill in a new name for our new faculty::
291
292  >>> ctrl = browser.getControl(name='form.title')
293  >>> ctrl.value = 'TestFac'
294
295Furthermore we add a prefix and a code (kind of abbreviation):
296
297  >>> browser.getControl(name='form.code').value = 'TF'
298
299Finally we click on 'Add Faculty' to add the new thing::
300
301  >>> browser.getControl('Add faculty').click()
302
303We can view a faculty by browsing a URL like this::
304
305  >>> browser.open('http://localhost/myuniversity/faculties/TF')
306
307Afterwards, the faculty should be visible:
308
309  >>> browser.open('http://localhost/myuniversity/faculties')
310  >>> print browser.contents
311  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
312  ...<h1>Academic Section</h1>
313  ...<td> <a href="TF"> <span>TF</span></a></td>
314  ...
315
316We can 'visit' each faculty by clicking on the appropriate link:
317
318  >>> browser.getLink('TF').click()
319  >>> print browser.contents
320  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
321  ...Faculty of TestFac (TF)...
322  ...
323
324If we add the same faculty twice, an error message will occur:
325
326  >>> browser.open('http://localhost/myuniversity/faculties/add')
327  >>> ctrl = browser.getControl(name='form.title')
328  >>> ctrl.value = 'TestFac'
329  >>> browser.getControl(name='form.code').value = 'TF'
330  >>> browser.getControl('Add faculty').click()
331  >>> 'The faculty code chosen already exists.' in browser.contents
332  True
333
334Modifying faculties
335-------------------
336
337A faculty can directly be reached by its code:
338
339  >>> browser.open('http://localhost/myuniversity/faculties/TF')
340
341We can change the settings for a faculty by clicking on the
342provided 'Manage  faculty' button:
343
344  >>> browser.getLink('Manage faculty').click()
345
346Let's set a new title and save the form:
347
348  >>> browser.getControl(name='form.title').value = "My renamed faculty"
349  >>> browser.getControl(name='form.actions.save').click()
350
351Our faculty was indeed renamed to ``My renamed faculty``:
352
353  >>> browser.open('http://localhost/myuniversity/faculties')
354  >>> print browser.contents
355  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
356  ...<h1>Academic Section</h1>
357  ...<td> <a href="TF"> <span>TF</span></a></td>
358  ...<td>Faculty of My renamed faculty (TF)</td>
359  ...
360
361We can grant local roles:
362
363  >>> root['myuniversity']['users'].addUser('bob', 'secret',title='Bob',
364  ...                               description='A sample user')
365  >>> browser.open('http://localhost/myuniversity/faculties/TF/manage')
366  >>> browser.getControl(name="user").value = ['bob']
367  >>> browser.getControl(
368  ...     name="local_role").value = ['waeup.local.DepartmentManager']
369  >>> browser.getControl("Add local role").click()
370  >>> print browser.contents
371  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
372  ...<td>bob</td>
373  ...
374
375On the portal user page the new local role is displayed:
376
377  >>> browser.getLink("Portal Users").click()
378  >>> print browser.contents
379  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
380  ...<td>Department Manager:...
381  ...
382
383The local role can be removed again:
384
385  >>> browser.open('http://localhost/myuniversity/faculties/TF/manage')
386  >>> ctrl = browser.getControl(name='role_id')
387  >>> browser.getControl("Remove selected local roles").click()
388  >>> print browser.contents
389  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
390  ...No local role selected...
391  ...
392
393  >>> browser.open('http://localhost/myuniversity/faculties/TF/manage')
394  >>> ctrl = browser.getControl(name='role_id')
395  >>> ctrl.getControl(value='bob|waeup.local.DepartmentManager').selected = True
396  >>> browser.getControl("Remove selected local roles").click()
397  >>> print browser.contents
398  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
399  ...Local role successfully removed...
400  ...
401
402Deleting faculties
403------------------
404
405  >>> browser.open('http://localhost/myuniversity/faculties/manage')
406  >>> browser.getControl('Cancel').click()
407  >>> print browser.url
408  http://localhost/myuniversity/faculties
409  >>> browser.getLink('Manage academic section').click()
410  >>> browser.getControl('Add faculty').click()
411  >>> ctrl = browser.getControl(name='form.title')
412  >>> ctrl.value = 'Second Faculty'
413  >>> browser.getControl(name='form.code').value = 'TF2'
414  >>> browser.getControl('Add faculty').click()
415  >>> browser.open('http://localhost/myuniversity/faculties/manage')
416  >>> browser.getControl("Remove selected", index=0).click()
417  >>> 'No item selected' in browser.contents
418  True
419  >>> browser.open('http://localhost/myuniversity/faculties/manage')
420  >>> ctrl = browser.getControl(name='val_id')
421  >>> ctrl.getControl(value='TF2').selected = True
422  >>> browser.getControl("Remove selected", index=0).click()
423  >>> print browser.contents
424  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
425  ...Successfully removed:...
426  ...
427
428Departments
429===========
430
431Adding departments
432------------------
433
434Departments are stored in :class:`IFaculty` instances with their code
435as key. Faculties therefore are also department containers. Faculties
436provides an add-form to add new departments:
437
438  >>> browser.open('http://localhost/myuniversity/faculties/TF/add')
439  >>> print browser.contents
440  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
441  ...*</span>
442  ...<span>Name of department</span>:
443  ...
444  >>> browser.getControl('Cancel').click()
445  >>> browser.open('http://localhost/myuniversity/faculties/TF/add')
446
447We fill in a new name for our new department:
448
449  >>> ctrl = browser.getControl(name='form.title')
450  >>> ctrl.value = 'TestDept'
451
452Furthermore we add a code (kind of abbreviation):
453
454  >>> browser.getControl(name='form.code').value = 'TD'
455
456Finally we click on 'Add Department' to add the new thing::
457
458  >>> browser.getControl('Add department').click()
459
460If we try to register a department under the same code twice we will
461get an error:
462
463  >>> browser.open('http://localhost/myuniversity/faculties/TF/add')
464  >>> ctrl = browser.getControl(name='form.title')
465  >>> ctrl.value = 'Another TestDept with same code'
466  >>> browser.getControl(name='form.code').value = 'TD'
467  >>> browser.getControl('Add department').click()
468  >>> print browser.contents
469  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
470  ...The code chosen already exists in this faculty...
471  ...
472
473We can view a department by browsing a URL like this::
474
475  >>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
476
477Afterwards, the department should be visible::
478
479  >>> browser.open('http://localhost/myuniversity/faculties/TF')
480  >>> print browser.contents
481  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
482  ...<h1>Departments</h1>
483  ...<td> <a href="TD"> <span>TD</span></a></td>
484  ...<td>Department of TestDept (TD)</td>
485  ...
486
487
488Modifying departments
489---------------------
490
491We can change the settings for a department by clicking on the
492provided 'Edit department' button:
493
494  >>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
495  >>> browser.getLink('Manage department').click()
496
497Let's set a new title and save the form:
498
499  >>> browser.getControl(name='form.title').value = "My test dept"
500  >>> browser.getControl(name='form.actions.save').click()
501
502Clicking 'Save' we will stay on the settings form. So we can change
503the department again.
504
505  >>> browser.getControl(name='form.title').value = "My renamed dept"
506  >>> ctrl = browser.getControl("Save")
507  >>> ctrl.click()
508
509
510Our department was indeed renamed to ``My renamed dept``:
511
512  >>> browser.open('http://localhost/myuniversity/faculties/TF')
513  >>> print browser.contents
514  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
515  ...<h1>Departments</h1>
516  ...<td> <a href="TD"> <span>TD</span></a></td>
517  ...<td>Department of My renamed dept (TD)</td>
518  ...
519
520We can grant local roles:
521
522  >>> browser.open('http://localhost/myuniversity/faculties/TF/TD/manage')
523  >>> browser.getControl(name="user").value = ['bob']
524  >>> browser.getControl(
525  ...     name="local_role").value = ['waeup.local.DepartmentManager']
526  >>> browser.getControl("Add local role").click()
527  >>> print browser.contents
528  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
529  ...<td>bob</td>
530  ...
531
532The local role can be removed again:
533
534  >>> browser.open('http://localhost/myuniversity/faculties/TF/TD/manage')
535  >>> ctrl = browser.getControl(name='role_id')
536  >>> browser.getControl("Remove selected local roles").click()
537  >>> print browser.contents
538  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
539  ...No local role selected...
540  ...
541
542  >>> browser.open('http://localhost/myuniversity/faculties/TF/TD/manage')
543  >>> ctrl = browser.getControl(name='role_id')
544  >>> ctrl.getControl(
545  ...     value='bob|waeup.local.DepartmentManager').selected = True
546  >>> browser.getControl("Remove selected local roles").click()
547  >>> print browser.contents
548  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
549  ...Local role successfully removed...
550  ...
551
552Deleting departments
553--------------------
554
555  >>> browser.open('http://localhost/myuniversity/faculties/TF/manage')
556  >>> browser.getControl('Cancel', index=0).click()
557  >>> print browser.url
558  http://localhost/myuniversity/faculties/TF
559  >>> browser.getLink('Manage faculty').click()
560  >>> browser.getControl('Add department').click()
561  >>> ctrl = browser.getControl(name='form.title')
562  >>> ctrl.value = 'Second Department'
563  >>> browser.getControl(name='form.code').value = 'TD2'
564  >>> browser.getControl('Add department').click()
565  >>> browser.open('http://localhost/myuniversity/faculties/TF/manage')
566  >>> browser.getControl("Remove selected", index=0).click()
567  >>> 'No item selected' in browser.contents
568  True
569  >>> browser.open('http://localhost/myuniversity/faculties/TF/manage')
570  >>> ctrl = browser.getControl(name='val_id')
571  >>> ctrl.getControl(value='TD2').selected = True
572  >>> browser.getControl("Remove selected", index=0).click()
573  >>> print browser.contents
574  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
575  ...Successfully removed:...
576  ...
577
578
579Courses
580=======
581
582Once we have a department, we can add courses.
583
584Adding courses
585--------------
586
587Courses are stored in :class:`ICoursesContainer` instances with their
588code as key. CoursesContainers are normally availabe as `course`
589attribute of :class:`waeup.kofa.university.department.Department`
590instances.
591
592To ease the life of users we do not require to browse the
593coursescontainers (which have a rather flat user interface), but
594provide adding of courses in department views.
595
596Each department provides a ``Add course`` action button near top.
597
598Departments provide an add-form to add new courses:
599
600  >>> dept_url = 'http://localhost/myuniversity/faculties/TF/TD'
601  >>> browser.open(dept_url + '/manage')
602  >>> browser.getControl('Add course').click()
603  >>> print browser.contents
604  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
605  ...*</span>
606  ...<span>Title of course</span>:
607  ...
608
609We fill in a name for our new course:
610
611  >>> ctrl = browser.getControl(name='form.title')
612  >>> ctrl.value = 'My Course 1'
613
614Furthermore we add a code (kind of abbreviation):
615
616  >>> browser.getControl(name='form.code').value = 'COURSE1'
617
618This course will take place in the the first semester, so we set the
619`semester` value to 1:
620
621  >>> ctrl = browser.getControl(name='form.semester')
622  >>> ctrl.options
623  ['1', '2', '3', '9']
624
625  >>> ctrl.displayOptions
626  ['First Semester', 'Second Semester', 'Combined', 'N/A']
627
628  >>> ctrl.value = ['1']
629
630Finally, we create the course:
631
632  >>> browser.getControl('Add course').click()
633
634If we try to register a course under the same code twice we will
635get an error:
636
637  >>> browser.open(dept_url + '/addcourse')
638  >>> ctrl = browser.getControl(name='form.title')
639  >>> ctrl.value = 'Another course with same code'
640  >>> browser.getControl(name='form.code').value = 'COURSE1'
641  >>> browser.getControl('Add course').click()
642  >>> print browser.contents
643  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
644  ...A course with same code already exists:...
645  ...
646
647Our course will be linked under the code on the department page:
648
649  >>> browser.open(dept_url)
650  >>> browser.getLink('COURSE1').click()
651  >>> browser.url
652  'http://localhost/myuniversity/faculties/TF/TD/courses/COURSE1'
653
654Before we really add a course we can cancel the action and will be
655redirected to the department page:
656
657  >>> browser.open(dept_url + '/addcourse')
658  >>> browser.getControl('Cancel').click()
659  >>> browser.url
660  'http://localhost/myuniversity/faculties/TF/TD'
661
662
663Modifying courses
664-----------------
665
666We can change the settings for a course by clicking on the provided
667'Edit settings' link:
668
669  >>> browser.open(dept_url + '/courses/COURSE1')
670  >>> browser.getLink('Edit course').click()
671
672When modifying a course, we cannot change the code any more:
673
674  >>> browser.getControl(name='form.code')
675  Traceback (most recent call last):
676  ...
677  LookupError: name 'form.code'
678
679Let's set a new title and save the form:
680
681  >>> browser.getControl(name='form.title').value = "My test course"
682  >>> browser.getControl(name='form.actions.save').click()
683
684Clicking 'Save' we will stay on the settings form. So we can change
685the course again. If we click ``Cancel`` nothing will be
686changed:
687
688  >>> browser.getControl(name='form.title').value = "Blah"
689  >>> browser.getControl('Cancel').click()
690
691Our course was not renamed to ``Blah``:
692
693  >>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
694  >>> print browser.contents
695  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
696  ...<td>My test course</td>...
697  ...
698
699Searching courses
700-----------------
701
702  >>> browser.open('http://localhost/myuniversity/faculties/search')
703  >>> browser.getControl(name='query').value = "My test course"
704  >>> browser.getControl('Search').click()
705  >>> print browser.contents
706  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
707  ...faculties/TF/TD/courses/COURSE1">COURSE1</a>
708  ...
709
710  >>> browser.open('http://localhost/myuniversity/faculties/search')
711  >>> browser.getControl(name='query').value = "COURSE1"
712  >>> browser.getControl('Search').click()
713  >>> print browser.contents
714  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
715  ...faculties/TF/TD/courses/COURSE1">COURSE1</a>
716  ...
717
718  >>> browser.getControl(name='query').value = "Nonsense"
719  >>> browser.getControl('Search').click()
720  >>> 'Search Results' in browser.contents
721  False
722
723  >>> browser.getControl(name='query').value = ""
724  >>> browser.getControl('Search').click()
725  >>> 'Empty search string' in browser.contents
726  True
727
728Deleting courses
729----------------
730
731We can delete courses by browsing the manage page of the containing
732department and checking the appropriate select box and clicking the
733´´Remove selected´´ button.
734
735  >>> browser.open(
736  ...     'http://localhost/myuniversity/faculties/TF/TD/@@manage#tab-2')
737  >>> 'My test course' in browser.contents
738  True
739
740  >>> browser.getControl('Cancel', index=0).click()
741  >>> browser.getLink('Manage department').click()
742  >>> browser.getControl('Remove selected courses').click()
743  >>> 'No item selected' in browser.contents
744  True
745
746  >>> browser.getControl(
747  ...    name='val_id').getControl(value='COURSE1').selected = True
748  >>> browser.getControl('Remove selected courses').click()
749
750  >>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
751  >>> 'My renamed course' in browser.contents
752  False
753
754
755Deleting departments with courses
756---------------------------------
757
758  >>> browser.open('http://localhost/myuniversity/faculties/TF/manage')
759  >>> browser.getControl('Cancel', index=0).click()
760  >>> browser.getLink('Manage faculty').click()
761  >>> browser.getControl('Add department').click()
762  >>> ctrl = browser.getControl(name='form.title')
763  >>> ctrl.value = 'Third Department'
764  >>> browser.getControl(name='form.code').value = 'TD3'
765  >>> browser.getControl('Add department').click()
766  >>> browser.open('http://localhost/myuniversity/faculties/TF/TD3/manage')
767  >>> browser.getControl('Add course').click()
768  >>> ctrl = browser.getControl(name='form.title')
769  >>> ctrl.value = 'My Course 5'
770  >>> browser.getControl(name='form.code').value = 'COURSE5'
771  >>> browser.getControl('Add course').click()
772  >>> browser.open('http://localhost/myuniversity/faculties/TF/manage')
773  >>> ctrl = browser.getControl(name='val_id')
774  >>> ctrl.getControl(value='TD3').selected = True
775  >>> browser.getControl("Remove selected", index=0).click()
776  >>> print browser.contents
777  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
778  ...Successfully removed:...
779  ...
780
781Certificates
782============
783
784Once we have a department, we can add also certificats.
785
786Adding certificates
787-------------------
788
789Certificates are stored in :class:`ICertificatesContainer` instances
790with their code as key. CertificatesContainers are normally availabe as
791`certificates` attribute of
792:class:`waeup.kofa.university.department.Department` instances.
793
794To ease the life of users we do not require to browse the
795certificatescontainers (which have in fact no user interface), but
796provide adding of certificates in department views.
797
798Each department provides a ``Add certificate`` action button near top.
799
800Departments provide an add-form to add new certificates:
801
802  >>> dept_url = 'http://localhost/myuniversity/faculties/TF/TD'
803  >>> browser.open(dept_url + '/manage')
804  >>> browser.getControl('Add certificate').click()
805  >>> print browser.contents
806  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
807  ...*</span>
808  ...<span>Title</span>:
809  ...
810
811We fill in a name for our new cert:
812
813  >>> ctrl = browser.getControl(name='form.title')
814  >>> ctrl.value = 'My Certificate 1'
815
816Furthermore we add a code (kind of abbreviation):
817
818  >>> browser.getControl(name='form.code').value = 'CERT1'
819
820Set the remaining required fields:
821
822  >>> browser.getControl(name='form.study_mode').value = ['ug_ft']
823  >>> browser.getControl(name='form.start_level').value = ['100']
824  >>> browser.getControl(name='form.end_level').value = ['400']
825  >>> browser.getControl(name='form.application_category').value = ['basic']
826
827Finally, we create the certificate:
828
829  >>> browser.getControl('Add certificate').click()
830
831If we try to register a certificate under the same code twice we will
832get an error:
833
834  >>> browser.open(dept_url + '/addcertificate')
835  >>> ctrl = browser.getControl(name='form.title')
836  >>> ctrl.value = 'Another cert with same code'
837  >>> browser.getControl(name='form.code').value = 'CERT1'
838  >>> browser.getControl(name='form.study_mode').value = ['ug_ft']
839  >>> browser.getControl(name='form.start_level').value = ['100']
840  >>> browser.getControl(name='form.end_level').value = ['400']
841  >>> browser.getControl(name='form.application_category').value = ['basic']
842
843  >>> browser.getControl('Add certificate').click()
844  >>> print browser.contents
845  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
846  ...A certificate with same code already exists:...
847  ...
848
849Our certificate will be linked under the code on the department page:
850
851  >>> browser.open(dept_url)
852  >>> browser.getLink('CERT1').click()
853  >>> browser.url
854  'http://localhost/myuniversity/faculties/TF/TD/certificates/CERT1'
855
856Before we really add a certificate we can cancel the action and will be
857redirected to the department page:
858
859  >>> browser.open(dept_url + '/addcertificate')
860  >>> browser.getControl('Cancel').click()
861  >>> browser.url
862  'http://localhost/myuniversity/faculties/TF/TD'
863
864
865Modifying certificates
866----------------------
867
868We can change the settings for a cert by clicking on the provided
869'Edit certificate' link:
870
871  >>> browser.open(dept_url + '/certificates/CERT1')
872  >>> browser.getLink('Manage certificate').click()
873
874When modifying a certificate, we cannot change the code any more:
875
876  >>> browser.getControl(name='form.code')
877  Traceback (most recent call last):
878  ...
879  LookupError: name 'form.code'
880
881Let's set a new title and save the form:
882
883  >>> browser.getControl(name='form.title').value = "My test cert"
884  >>> browser.getControl(name='form.actions.save').click()
885
886Clicking 'Save' we will stay on the settings form. So we can change
887the cert again.
888
889  >>> browser.getControl(name='form.title').value = "My renamed cert"
890  >>> ctrl = browser.getControl("Save",index=0)
891  >>> ctrl.click()
892
893If we go to the settings page and click ``Cancel`` nothing will be
894changed:
895
896  >>> browser.getControl(name='form.title').value = "Blah"
897  >>> browser.getControl('Cancel',index=0).click()
898
899Our certificate was indeed renamed to ``My renamed cert`` and not to
900``Blah``:
901
902  >>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
903  >>> print browser.contents
904  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
905  ...<td>My renamed cert</td>...
906  ...
907
908Searching certificates
909----------------------
910
911  >>> browser.open('http://localhost/myuniversity/faculties/search')
912  >>> browser.getControl(name='query').value = "My renamed cert"
913  >>> browser.getControl('Search').click()
914  >>> print browser.contents
915  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
916  ...faculties/TF/TD/certificates/CERT1">CERT1</a>
917  ...
918
919  >>> browser.open('http://localhost/myuniversity/faculties/search')
920  >>> browser.getControl(name='query').value = "CERT1"
921  >>> browser.getControl('Search').click()
922  >>> print browser.contents
923  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
924  ...faculties/TF/TD/certificates/CERT1">CERT1</a>
925  ...
926
927Deleting certificates
928---------------------
929
930We can delete certificates by browsing the manage page of the
931containing department and checking the appropriate select box and
932clicking the ´´Remove selected´´ button.
933
934  >>> browser.open(
935  ...    'http://localhost/myuniversity/faculties/TF/TD/@@manage#tab-3')
936  >>> 'My renamed cert' in browser.contents
937  True
938
939  >>> browser.getControl('Remove selected certificates').click()
940  >>> 'No item selected' in browser.contents
941  True
942
943  >>> browser.getControl(name='val_id').getControl(
944  ...    value='CERT1').selected = True
945  >>> browser.getControl('Remove selected certificates').click()
946  >>> 'My renamed cert' in browser.contents
947  False
948
949
950CertificateCourses
951==================
952
953Once we have a certificate, we can add also certificate courses. These
954are referrers of courses with some extra data.
955
956Before we can work with certificate courses, we need some certificates
957and courses to be available.
958
959  >>> browser.open(dept_url + '/addcourse')
960  >>> ctrl = browser.getControl(name='form.title')
961  >>> ctrl.value = 'Another course with same code'
962  >>> browser.getControl(name='form.code').value = 'COURSE1'
963  >>> browser.getControl(name='form.title').value = 'Course 1'
964  >>> browser.getControl('Add course').click()
965
966  >>> browser.open(dept_url + '/addcourse')
967  >>> ctrl = browser.getControl(name='form.title')
968  >>> ctrl.value = 'Another course with same code'
969  >>> browser.getControl(name='form.code').value = 'COURSE2'
970  >>> browser.getControl(name='form.title').value = 'Course 2'
971  >>> browser.getControl('Add course').click()
972
973  >>> browser.open(dept_url + '/addcertificate')
974  >>> ctrl = browser.getControl(name='form.title')
975  >>> ctrl.value = 'Another cert with same code'
976  >>> browser.getControl(name='form.code').value = 'CERT1'
977  >>> browser.getControl(name='form.title').value = 'Certificate 1'
978  >>> browser.getControl(name='form.study_mode').value = ['ug_ft']
979  >>> browser.getControl(name='form.start_level').value = ['100']
980  >>> browser.getControl(name='form.end_level').value = ['400']
981  >>> browser.getControl(name='form.application_category').value = ['basic']
982  >>> browser.getControl('Add certificate').click()
983
984  >>> browser.open(dept_url + '/addcertificate')
985  >>> ctrl = browser.getControl(name='form.title')
986  >>> ctrl.value = 'Another cert with same code'
987  >>> browser.getControl(name='form.code').value = 'CERT2'
988  >>> browser.getControl(name='form.title').value = 'Certificate 2'
989  >>> browser.getControl(name='form.study_mode').value = ['ug_ft']
990  >>> browser.getControl(name='form.start_level').value = ['100']
991  >>> browser.getControl(name='form.end_level').value = ['400']
992  >>> browser.getControl(name='form.application_category').value = ['basic']
993  >>> browser.getControl('Add certificate').click()
994
995
996Adding certificatecourses
997-------------------------
998
999Certcourses are stored in :class:`ICertificate` instances
1000with their code as key.
1001
1002Each certificate provides a ``Add certificate course`` action button near top.
1003
1004Certificates provide an add-form to add new certcourses:
1005
1006  >>> cert_url = dept_url + '/certificates/CERT1'
1007  >>> browser.open(cert_url + '/manage')
1008  >>> browser.getControl('Add certificate course').click()
1009  >>> print browser.contents
1010  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
1011  ...*</span>
1012  ...<span>Level</span>:
1013  ...
1014
1015In the add-form we will get a list of available courses to select
1016from. This list will contain all courses stored in the site, not only
1017the ones from local department:
1018
1019  >>> ctrl = browser.getControl(name='form.course')
1020  >>> ctrl.displayOptions
1021  ['--', 'COURSE1 - Course 1', 'COURSE2 - Course 2']
1022
1023We select the first course and create our certificatecourse:
1024
1025  >>> ctrl.getControl('COURSE1').selected = True
1026  >>> browser.getControl(name='form.level').value = ['100']
1027  >>> browser.getControl('Add certificate course').click()
1028
1029Our certificatecourse will be linked on the parent certificate page:
1030
1031  >>> browser.open(cert_url)
1032  >>> browser.getLink('COURSE1_100').click()
1033  >>> browser.url
1034  'http://localhost/my...sity/faculties/TF/TD/certificates/CERT1/COURSE1_100'
1035
1036We can't add the same certificatecourse twice:
1037
1038  >>> cert_url = dept_url + '/certificates/CERT1'
1039  >>> browser.open(cert_url + '/manage')
1040  >>> browser.getControl('Add certificate course').click()
1041  >>> ctrl = browser.getControl(name='form.course')
1042  >>> ctrl.getControl('COURSE1').selected = True
1043  >>> browser.getControl(name='form.level').value = ['100']
1044  >>> browser.getControl('Add certificate course').click()
1045  >>> 'The chosen certificate course is already' in browser.contents
1046  True
1047
1048When we started to add a new certificatecourse, we can also cancel the
1049process before submitting. This will bring us back to the certificate
1050page:
1051
1052  >>> browser.open(cert_url + '/addcertificatecourse')
1053  >>> browser.getControl('Cancel').click()
1054  >>> browser.url
1055  'http://localhost/myuniversity/faculties/TF/TD/certificates/CERT1'
1056
1057
1058Modifying certificatecourses
1059----------------------------
1060
1061We can change the settings for a certcourse by clicking on the
1062provided 'Edit certificate course' link:
1063
1064  >>> browser.open(cert_url + '/COURSE1_100')
1065  >>> browser.getLink('Edit certificate course').click()
1066
1067If we just click 'Save and return' nothing will change:
1068
1069  >>> browser.getControl("Save and return").click()
1070  >>> browser.getLink('COURSE1_100').click()
1071  >>> browser.url
1072  'http://localhost/myun.../TF/TD/certificates/CERT1/COURSE1_100'
1073
1074Let's set a new level (it was 100 before) and save the form. This will
1075bring us to the certificate index page afterwards:
1076
1077  >>> browser.open(cert_url + '/COURSE1_100/manage')
1078  >>> browser.getControl(name='form.level').value = ['200']
1079  >>> browser.getControl("Save and return").click()
1080
1081As we changed the level, also the URL will change:
1082
1083  >>> browser.getLink('COURSE1_200').click()
1084  >>> browser.url
1085  'http://localhost/myun.../TF/TD/certificates/CERT1/COURSE1_200'
1086
1087If we go to the settings page and click ``Cancel`` nothing will be
1088changed:
1089
1090  >>> browser.getLink('Edit certificate course').click()
1091  >>> browser.getControl(name='form.level').value = ['400']
1092  >>> browser.getControl('Cancel').click()
1093
1094Our certcourse provides a new level of 200 and not 400:
1095
1096  >>> browser.open(cert_url + '/COURSE1_200')
1097  >>> print browser.contents
1098  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1099  ...<td>Level:</td>
1100  ...<td>200 (Year 2)</td>
1101  ...
1102
1103Searching certificatecourses
1104----------------------------
1105
1106  >>> browser.open('http://localhost/myuniversity/faculties/search')
1107  >>> browser.getControl(name='query').value = "COURSE1"
1108  >>> browser.getControl('Search').click()
1109  >>> print browser.contents
1110  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
1111  ...faculties/TF/TD/certificates/CERT1/COURSE1_200">COURSE1</a>
1112  ...
1113
1114  >>> browser.getControl(name='query').value = "*"
1115  >>> browser.getControl('Search').click()
1116  >>> 'Search string not allowed' in browser.contents
1117  True
1118
1119Deleting certificatecourses
1120---------------------------
1121
1122We can delete certcourses by browsing the containing certificate manage page:
1123
1124  >>> browser.open(cert_url + '/manage#tab-2')
1125  >>> 'COURSE1_200</a>' in browser.contents
1126  True
1127  >>> browser.getControl('Remove selected certificate courses').click()
1128  >>> 'No item selected' in browser.contents
1129  True
1130  >>> browser.getControl(name='val_id').getControl(
1131  ...    value='COURSE1_200').selected = True
1132  >>> browser.getControl('Remove selected certificate courses').click()
1133  >>> 'Successfully removed: COURSE1_200' in browser.contents
1134  True
1135
1136  >>> 'COURSE1_200</a>' in browser.contents
1137  False
1138
1139
1140
1141Data Center
1142===========
1143
1144The data center helps us uploading files for later import or similar.
1145
1146  >>> browser.open('http://localhost/myuniversity')
1147  >>> browser.getLink('Data Center').click()
1148
1149Setting the file path
1150---------------------
1151
1152A datacenter stores files in a path in filesystem. By default this is
1153a directory in the sources:
1154
1155  >>> print browser.contents
1156  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1157  ...
1158  <b>Storage path:</b> <span>.../parts/test/datacenter</span>
1159  ...
1160
1161Going to 'Settings` we can change the path:
1162
1163  >>> browser.getLink('Edit settings').click()
1164  >>> pathsetting = browser.getControl(name='newpath')
1165
1166We create a directory and set it as our upload path:
1167
1168  >>> import os
1169  >>> cwd = os.getcwd()
1170  >>> uploadpath = os.path.join(cwd, 'testfiles')
1171  >>> os.mkdir(uploadpath)
1172  >>> pathsetting.value = uploadpath
1173
1174And submit the form:
1175
1176  >>> browser.getControl(name='save').click()
1177
1178We clean up the set directory path, as there might be some files be
1179copied some files from installation:
1180
1181  >>> files = os.listdir(uploadpath)
1182  >>> for filename in files:
1183  ...   if os.path.isdir(os.path.join(uploadpath, filename)):
1184  ...     continue
1185  ...   os.unlink(os.path.join(uploadpath, filename))
1186
1187We also remove any existing 'accesscodes' subdir:
1188
1189  >>> import shutil
1190  >>> for filename in files:
1191  ...   if not os.path.isdir(os.path.join(uploadpath, filename)):
1192  ...     continue
1193  ...   if filename != 'accesscodes':
1194  ...     continue
1195  ...   shutil.rmtree(os.path.join(uploadpath, filename))
1196
1197The new upload directory is now empty, except from the logs and other
1198standard dirs, which are created automatically:
1199
1200  >>> sorted(os.listdir(uploadpath))
1201  ['deleted', 'finished', 'logs', 'unfinished']
1202
1203
1204Uploading files
1205---------------
1206
1207Now we can upload files. Most interesting files might be CSV files,
1208that can be imported lateron. We create a CSV file containing faculty
1209descriptions:
1210
1211  >>> open('faculties.csv', 'wb').write(
1212  ... """code,title,title_prefix
1213  ... FA,Arts,faculty
1214  ... FS,Sciences,faculty
1215  ... """)
1216
1217Now we can upload this file. To do this, we first go to the upload
1218page:
1219
1220  >>> browser.getLink('Upload data').click()
1221
1222and enter the appropriate data in the form:
1223
1224  >>> filewidget = browser.getControl(name='uploadfile:file')
1225  >>> filewidget
1226  <Control name='uploadfile:file' type='file'>
1227
1228A sidenote for developers: by marking the filewidget with the
1229``:file`` extension, we tell Zope to handle this field as a file
1230widget.
1231
1232  >>> import cStringIO
1233  >>> filecontents = cStringIO.StringIO(
1234  ...   open('faculties.csv', 'rb').read())
1235  >>> filewidget.add_file(filecontents, 'text/plain', 'myfaculties.csv')
1236
1237  >>> browser.getControl(name='SUBMIT').click()
1238
1239The file was indeed uploaded, with the current userid inserted:
1240
1241  >>> sorted(os.listdir(uploadpath))
1242  ['deleted', 'finished', 'logs', 'myfaculties_zope.mgr.csv', 'unfinished']
1243
1244We create and upload also a CSV file containing departments:
1245
1246  >>> open('departments.csv', 'wb').write(
1247  ... """code,title,title_prefix,faculty_code
1248  ... LIT,Literature,department,FA
1249  ... SOC,Sociology,department,FA
1250  ... PHY,Physics,department,FS
1251  ... INF,Informatics,department,FS
1252  ... MAT,Math,department,FS
1253  ... """)
1254
1255  >>> browser.open('http://localhost/myuniversity/datacenter/upload')
1256  >>> browser.getControl(name='uploadfile:file').add_file(
1257  ...   cStringIO.StringIO(open('departments.csv', 'rb').read()),
1258  ...   'text/plain', 'mydepartments.csv')
1259  >>> browser.getControl(name='SUBMIT').click()
1260
1261We create and upload also a CSV file containing courses:
1262
1263  >>> open('courses.csv', 'wb').write(
1264  ... """code,level,title,passmark,credits,semester,faculty,department
1265  ... LI1,,Introduction to Literature I,40,2,1,FA,LIT
1266  ... LI2,,Introduction to Literature II,40,2,2,FA,LIT
1267  ... AN1,000,Analysis I,40,2,1,FS,MAT
1268  ... AN2,000,Analysis II,40,2,2,FS,MAT
1269  ... """)
1270
1271  >>> browser.open('http://localhost/myuniversity/datacenter/upload')
1272  >>> browser.getControl(name='uploadfile:file').add_file(
1273  ...   cStringIO.StringIO(open('courses.csv', 'rb').read()),
1274  ...   'text/plain', 'mycourses.csv')
1275  >>> browser.getControl(name='SUBMIT').click()
1276
1277We create and upload also a CSV file containing certificates:
1278
1279  >>> open('certificates.csv', 'wb').write(
1280  ... """code,title,faculty_code,department_code,study_mode,end_level,m_prefix,start_level,application_category
1281  ... LBA,BACHELOR OF LITERATURE,FA,LIT,UG,ug_ft,500,LIT,100,basic
1282  ... LMA,MASTER OF LITERATURE,FA,LIT,UG,ug_pt,500,LIT,100,cest
1283  ... DME,DIPLOMA OF MATH,FS,MAT,DP,dp_ft,200,DME,100,cest
1284  ... """)
1285
1286  >>> browser.open('http://localhost/myuniversity/datacenter/upload')
1287  >>> browser.getControl(name='uploadfile:file').add_file(
1288  ...   cStringIO.StringIO(open('certificates.csv', 'rb').read()),
1289  ...   'text/plain', 'mycertificates.csv')
1290  >>> browser.getControl(name='SUBMIT').click()
1291
1292We create and upload also a CSV file containing certificate courses:
1293
1294  >>> open('certcourses.csv', 'wb').write(
1295  ... """code,faculty_code,department_code,certificate_code,level,mandatory
1296  ... LI1,FA,LIT,LBA,100,True
1297  ... LI2,FA,LIT,LBA,200,True
1298  ... """)
1299
1300  >>> browser.open('http://localhost/myuniversity/datacenter/upload')
1301  >>> browser.getControl(name='uploadfile:file').add_file(
1302  ...   cStringIO.StringIO(open('certcourses.csv', 'rb').read()),
1303  ...   'text/plain', 'mycertcourses.csv')
1304  >>> browser.getControl(name='SUBMIT').click()
1305
1306
1307Importing a CSV file
1308--------------------
1309
1310The import of CSV files is described in batchprocessing.txt.
1311
1312
1313Clean up:
1314
1315  >>> import os
1316  >>> import shutil
1317  >>> shutil.rmtree(uploadpath)
1318
Note: See TracBrowser for help on using the repository browser.