Browsing the WAeUP portal
*************************
Here we visit all parts of a WAeUP portal using a browser.
:Test-Layer: functional
University
==========
We can watch universities in the browser.
To make sure, we can 'watch' pages, we first have to initialize out
test browser::
>>> from zope.testbrowser.testing import Browser
>>> browser = Browser()
>>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
>>> browser.handleErrors = False
We create an university object and put into the ZODB root::
>>> root = getRootFolder()
>>> list(root)
[]
>>> from waeup.sirp.app import University
>>> u = University()
>>> root['myuniversity'] = u
>>> list(root)
[u'myuniversity']
Let's get the default view of a university::
>>> browser.open('http://localhost/myuniversity')
>>> print browser.contents
>> browser.open('http://localhost/myuniversity/manage')
>>> print browser.contents
>> 'Sample University' in browser.contents
True
We can export a university as XML::
>>> browser.open('http://localhost/myuniversity/export.xml')
>>> print browser.contents
...
>>> print browser.headers
Status: 200 Ok
Content-Length: ...
Content-Type: text/xml; charset=UTF-8
X-Powered-By: Zope (www.zope.org), Python (www.python.org)
Faculties
=========
Faculties are stored in a special container of `IUniversity`
instances. The container is called ``faculties`` and provides an
add-form to add new faculties::
>>> browser.open('http://localhost/myuniversity/faculties/add')
>>> print browser.contents
*Name of Faculty
...
We fill in a new name for our new faculty::
>>> ctrl = browser.getControl(name='form.title')
>>> ctrl.value = 'TestFac'
Furthermore we add a prefix and a code (kind of abbreviation):
>>> browser.getControl(name='form.code').value = 'TF'
Finally we click on 'Add Faculty' to add the new thing::
>>> browser.getControl('Add faculty').click()
We can view a faculty by browsing a URL like this::
>>> browser.open('http://localhost/myuniversity/faculties/TF')
Afterwards, the faculty should be visible:
>>> browser.open('http://localhost/myuniversity/faculties')
>>> print browser.contents
Registered Faculties
...
TF | Faculty of TestFac |
...
We can 'visit' each faculty by clicking on the appropriate link:
>>> browser.getLink('TF').click()
>>> print browser.contents
Faculty of TestFac (TF)...
...
Modifying faculties
-------------------
A faculty can directly be reached by its code:
>>> browser.open('http://localhost/myuniversity/faculties/TF')
We can change the settings for a faculty by clicking on the
provided 'Edit settings' button:
>>> browser.getLink('Edit settings').click()
Let's set a new title and save the form:
>>> browser.getControl(name='form.title').value = "My test faculty"
>>> browser.getControl(name='form.actions.save').click()
Clicking 'Save' we will stay on the settings form. So we can change
the department again. This time we will return to the overview page
afterwards:
>>> browser.getControl(name='form.title').value = "My renamed faculty"
>>> ctrl = browser.getControl("Save and return")
>>> ctrl.click()
If we go to the settings page and click ``Cancel`` nothing will be
changed:
>>> browser.getLink('Edit settings').click()
>>> browser.getControl(name='form.title').value = "Blah"
>>> browser.getControl('Cancel').click()
Our faculty was indeed renamed to ``My renamed faculty`` and not to
``Blah``:
>>> browser.open('http://localhost/myuniversity/faculties')
>>> print browser.contents
Registered Faculties
...TF | Faculty of My renamed faculty |
...
Departments
===========
Adding departments
------------------
Departments are stored in :class:`IFaculty` instances with their code
as key. Faculties therefore are also department containers. Faculties
provides an add-form to add new departments:
>>> browser.open('http://localhost/myuniversity/faculties/TF/add')
>>> print browser.contents
*Name of Department
...
We fill in a new name for our new department:
>>> ctrl = browser.getControl(name='form.title')
>>> ctrl.value = 'TestDept'
Furthermore we add a code (kind of abbreviation):
>>> browser.getControl(name='form.code').value = 'TD'
Finally we click on 'Add Department' to add the new thing::
>>> browser.getControl('Add department').click()
If we try to register a department under the same code twice we will
get an error:
>>> browser.open('http://localhost/myuniversity/faculties/TF/add')
>>> ctrl = browser.getControl(name='form.title')
>>> ctrl.value = 'Another TestDept with same code'
>>> browser.getControl(name='form.code').value = 'TD'
>>> browser.getControl('Add department').click()
>>> print browser.contents
The code chosen already exists in the database
...
We can view a department by browsing a URL like this:
>>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
Afterwards, the department should be visible:
>>> browser.open('http://localhost/myuniversity/faculties/TF')
>>> print browser.contents
Registered Departments:
...TD | Department of TestDept |
...
Modifying departments
---------------------
We can change the settings for a department by clicking on the
provided 'Edit settings' button:
>>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
>>> browser.getLink('Edit settings').click()
Let's set a new title and save the form:
>>> browser.getControl(name='form.title').value = "My test dept"
>>> browser.getControl(name='form.actions.save').click()
Clicking 'Save' we will stay on the settings form. So we can change
the department again. This time we will return to the overview page
afterwards:
>>> browser.getControl(name='form.title').value = "My renamed dept"
>>> ctrl = browser.getControl("Save and return")
>>> ctrl.click()
If we go to the settings page and click ``Cancel`` nothing will be
changed:
>>> browser.getLink('Edit settings').click()
>>> browser.getControl(name='form.title').value = "Blah"
>>> browser.getControl('Cancel').click()
Our department was indeed renamed to ``My renamed dept`` and not to
``Blah``:
>>> browser.open('http://localhost/myuniversity/faculties/TF')
>>> print browser.contents
Registered Departments:
...TD | Department of My renamed dept |
...
Courses
=======
Once we have a department, we can add courses.
Adding courses
--------------
Courses are stored in :class:`ICourseContainer` instances with their
code as key. CourseContainers are normally availabe as `course`
attribute of :class:`waeup.sirp.university.department.Department`
instances.
To ease the life of users we do not require to browse the
coursecontainers (which have a rather flat user interface), but
provide adding of courses in department views.
Each department provides a ``Add course`` action button near top.
Departments provide an add-form to add new courses:
>>> dept_url = 'http://localhost/myuniversity/faculties/TF/TD'
>>> browser.open(dept_url + '/addcourse')
>>> print browser.contents
*Title of course
...
We fill in a name for our new course:
>>> ctrl = browser.getControl(name='form.title')
>>> ctrl.value = 'My Course 1'
Furthermore we add a code (kind of abbreviation):
>>> browser.getControl(name='form.code').value = 'COURSE1'
This course will take place in the the first semester, so we set the
`semester` value to 1:
>>> ctrl = browser.getControl(name='form.semester')
>>> ctrl.options
['0', '1', '2', '3']
>>> ctrl.displayOptions
['N/A', 'First Semester', 'Second Semester', 'Combined']
>>> ctrl.value = ['1']
Finally, we create the course:
>>> browser.getControl('Add course').click()
If we try to register a course under the same code twice we will
get an error:
>>> browser.open(dept_url + '/addcourse')
>>> ctrl = browser.getControl(name='form.title')
>>> ctrl.value = 'Another course with same code'
>>> browser.getControl(name='form.code').value = 'COURSE1'
>>> browser.getControl('Add course').click()
>>> print browser.contents
The code chosen already exists in the database
...
Our course will be linked under the code on the department page:
>>> browser.open(dept_url)
>>> browser.getLink('COURSE1').click()
>>> browser.url
'http://localhost/myuniversity/faculties/TF/TD/courses/COURSE1'
Before we really add a course we can cancel the action and will be
redirected to the department page:
>>> browser.open(dept_url + '/addcourse')
>>> browser.getControl('Cancel').click()
>>> browser.url
'http://localhost/myuniversity/faculties/TF/TD'
Modifying courses
-----------------
We can change the settings for a course by clicking on the provided
'Edit settings' link:
>>> browser.open(dept_url + '/courses/COURSE1')
>>> browser.getLink('Edit settings').click()
When modifying a course, we cannot change the code any more:
>>> browser.getControl(name='form.code')
Traceback (most recent call last):
...
LookupError: name 'form.code'
Let's set a new title and save the form:
>>> browser.getControl(name='form.title').value = "My test course"
>>> browser.getControl(name='form.actions.save').click()
Clicking 'Save' we will stay on the settings form. So we can change
the course again. This time we will return to the overview page
afterwards:
>>> browser.getControl(name='form.title').value = "My renamed course"
>>> ctrl = browser.getControl("Save and return")
>>> ctrl.click()
If we go to the settings page and click ``Cancel`` nothing will be
changed:
>>> browser.getLink('Edit settings').click()
>>> browser.getControl(name='form.title').value = "Blah"
>>> browser.getControl('Cancel').click()
Our course was indeed renamed to ``My renamed course`` and not to
``Blah``:
>>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
>>> print browser.contents
...My renamed course | ...
...
Deleting courses
----------------
We can delete courses by browsing the containing department and
clicking on the appropriate 'Delete' button. As we have only one
course, there is only one 'Delete' button yet:
>>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
>>> 'My renamed course' in browser.contents
True
>>> browser.getControl('Delete').click()
>>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
>>> 'My renamed course' in browser.contents
False
Certificates
============
Once we have a department, we can add also certificats.
Adding certificates
-------------------
Certificates are stored in :class:`ICertificateContainer` instances
with their code as key. CertificateContainers are normally availabe as
`certificates` attribute of
:class:`waeup.sirp.university.department.Department` instances.
To ease the life of users we do not require to browse the
certificatecontainers (which have in fact no user interface), but
provide adding of certificates in department views.
Each department provides a ``Add certificate`` action button near top.
Departments provide an add-form to add new certificates:
>>> dept_url = 'http://localhost/myuniversity/faculties/TF/TD'
>>> browser.open(dept_url + '/addcertificate')
>>> print browser.contents
*title
...
We fill in a name for our new cert:
>>> ctrl = browser.getControl(name='form.title')
>>> ctrl.value = 'My Certificate 1'
Furthermore we add a code (kind of abbreviation):
>>> browser.getControl(name='form.code').value = 'CERT1'
Set the remaining required fields:
>>> browser.getControl(name='form.study_mode').value = 'combined'
>>> browser.getControl(name='form.start_level').value = '100'
>>> browser.getControl(name='form.end_level').value = '400'
>>> browser.getControl(name='form.application_category').value = 'UME'
>>> browser.getControl(name='form.max_pass').value = '400'
Finally, we create the certificate:
>>> browser.getControl('Add certificate').click()
If we try to register a certificate under the same code twice we will
get an error:
>>> browser.open(dept_url + '/addcertificate')
>>> ctrl = browser.getControl(name='form.title')
>>> ctrl.value = 'Another cert with same code'
>>> browser.getControl(name='form.code').value = 'CERT1'
>>> browser.getControl(name='form.study_mode').value = 'combined'
>>> browser.getControl(name='form.start_level').value = '100'
>>> browser.getControl(name='form.end_level').value = '400'
>>> browser.getControl(name='form.application_category').value = 'UME'
>>> browser.getControl(name='form.max_pass').value = '400'
>>> browser.getControl('Add certificate').click()
>>> print browser.contents
The name chosen already exists in the database
...
Our certificate will be linked under the code on the department page:
>>> browser.open(dept_url)
>>> browser.getLink('CERT1').click()
>>> browser.url
'http://localhost/myuniversity/faculties/TF/TD/certificates/CERT1'
Before we really add a certificate we can cancel the action and will be
redirected to the department page:
>>> browser.open(dept_url + '/addcertificate')
>>> browser.getControl('Cancel').click()
>>> browser.url
'http://localhost/myuniversity/faculties/TF/TD'
Modifying certificates
----------------------
We can change the settings for a cert by clicking on the provided
'Edit settings' link:
>>> browser.open(dept_url + '/certificates/CERT1')
>>> browser.getLink('Edit settings').click()
When modifying a certificate, we cannot change the code any more:
>>> browser.getControl(name='form.code')
Traceback (most recent call last):
...
LookupError: name 'form.code'
Let's set a new title and save the form:
>>> browser.getControl(name='form.title').value = "My test cert"
>>> browser.getControl(name='form.actions.save').click()
Clicking 'Save' we will stay on the settings form. So we can change
the cert again. This time we will return to the overview page
afterwards:
>>> browser.getControl(name='form.title').value = "My renamed cert"
>>> ctrl = browser.getControl("Save and return")
>>> ctrl.click()
If we go to the settings page and click ``Cancel`` nothing will be
changed:
>>> browser.getLink('Edit settings').click()
>>> browser.getControl(name='form.title').value = "Blah"
>>> browser.getControl('Cancel').click()
Our certificate was indeed renamed to ``My renamed cert`` and not to
``Blah``:
>>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
>>> print browser.contents
...My renamed cert | ...
...
Deleting certificates
---------------------
We can delete certificates by browsing the containing department and
clicking on the appropriate 'Delete' button. As we have only one
certificate, there is only one 'Delete' button yet:
>>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
>>> 'My renamed cert' in browser.contents
True
>>> browser.getControl('Delete').click()
>>> browser.open('http://localhost/myuniversity/faculties/TF/TD')
>>> 'My renamed cert' in browser.contents
False
CertificateCourses
==================
Once we have a certificate, we can add also certificate courses. These
are references to courses with some extra data.
Before we can work with certificate courses, we need some certificates
and courses to be available.
>>> browser.open(dept_url + '/addcourse')
>>> ctrl = browser.getControl(name='form.title')
>>> ctrl.value = 'Another course with same code'
>>> browser.getControl(name='form.code').value = 'COURSE1'
>>> browser.getControl(name='form.title').value = 'Course 1'
>>> browser.getControl('Add course').click()
>>> browser.open(dept_url + '/addcourse')
>>> ctrl = browser.getControl(name='form.title')
>>> ctrl.value = 'Another course with same code'
>>> browser.getControl(name='form.code').value = 'COURSE2'
>>> browser.getControl(name='form.title').value = 'Course 2'
>>> browser.getControl('Add course').click()
>>> browser.open(dept_url + '/addcertificate')
>>> ctrl = browser.getControl(name='form.title')
>>> ctrl.value = 'Another cert with same code'
>>> browser.getControl(name='form.code').value = 'CERT1'
>>> browser.getControl(name='form.title').value = 'Certificate 1'
>>> browser.getControl(name='form.study_mode').value = 'combined'
>>> browser.getControl(name='form.start_level').value = '100'
>>> browser.getControl(name='form.end_level').value = '400'
>>> browser.getControl(name='form.application_category').value = 'UME'
>>> browser.getControl(name='form.max_pass').value = '400'
>>> browser.getControl('Add certificate').click()
>>> browser.open(dept_url + '/addcertificate')
>>> ctrl = browser.getControl(name='form.title')
>>> ctrl.value = 'Another cert with same code'
>>> browser.getControl(name='form.code').value = 'CERT2'
>>> browser.getControl(name='form.title').value = 'Certificate 2'
>>> browser.getControl(name='form.study_mode').value = 'combined'
>>> browser.getControl(name='form.start_level').value = '100'
>>> browser.getControl(name='form.end_level').value = '400'
>>> browser.getControl(name='form.application_category').value = 'UME'
>>> browser.getControl(name='form.max_pass').value = '400'
>>> browser.getControl('Add certificate').click()
Adding certificatecourses
-------------------------
Certcourses are stored in :class:`ICertificate` instances
with their code as key.
Each certificate provides a ``Add course`` action button near top.
Certificates provide an add-form to add new certcourses:
>>> cert_url = dept_url + '/certificates/CERT1'
>>> browser.open(cert_url + '/addcertificatecourse')
>>> print browser.contents
*Level of this course
...
In the add-form we will get a list of available courses to select
from. This list will contain all courses stored in the site, not only
the ones from local department:
>>> ctrl = browser.getControl(name='form.course')
>>> ctrl.displayOptions
['(no value)', 'COURSE1 Course 1', 'COURSE2 Course 2']
We select the first course and create our certificatecourse:
>>> ctrl.getControl('COURSE1').selected = True
>>> browser.getControl('Add course').click()
Our certificatecourse will be linked on the parent certificate page:
>>> browser.open(cert_url)
>>> browser.getLink('COURSE1').click()
>>> browser.url
'http://localhost/my...sity/faculties/TF/TD/certificates/CERT1/COURSE1_100'
When we started to add a new certificatecourse, we can also cancel the
process before submitting. This will bring us back to the certificate
page:
>>> browser.open(cert_url + '/addcertificatecourse')
>>> browser.getControl('Cancel').click()
>>> browser.url
'http://localhost/myuniversity/faculties/TF/TD/certificates/CERT1'
Modifying certificatecourses
----------------------------
We can change the settings for a certcourse by clicking on the
provided 'Edit settings' link:
>>> browser.open(cert_url + '/COURSE1_100')
>>> browser.getLink('Edit settings').click()
Let's set a new level (it was 100 before) and save the form. This will
bring us to the certificate index page afterwards:
>>> browser.getControl(name='form.level').value = "200"
>>> ctrl = browser.getControl("Save and return")
>>> ctrl.click()
As we changed the level, also the URL will change:
>>> browser.getLink('COURSE1').click()
>>> browser.url
'http://localhost/myun.../TF/TD/certificates/CERT1/COURSE1_200'
If we go to the settings page and click ``Cancel`` nothing will be
changed:
>>> browser.getLink('Edit settings').click()
>>> browser.getControl(name='form.level').value = "666"
>>> browser.getControl('Cancel').click()
Our certcourse provides a new level of 200 and not 666:
>>> browser.open(cert_url + '/COURSE1_200')
>>> print browser.contents
>> browser.open(cert_url)
>>> 'COURSE1_200' in browser.contents
True
>>> browser.getControl('delete').click()
>>> browser.open(cert_url)
>>> 'COURSE1_200' in browser.contents
False
Data Center
===========
The data center helps us uploading files for later import or similar.
>>> browser.open('http://localhost/myuniversity')
>>> browser.getLink('Data Center').click()
Setting the file path
---------------------
A datacenter stores files in a path in filesystem. By default this is
a directory in the sources:
>>> print browser.contents
Storage path: /.../waeup/sirp/files
...
Going to 'Settings` we can change the path:
>>> browser.getLink('Edit settings').click()
>>> pathsetting = browser.getControl(name='newpath')
We create a directory and set it as our upload path:
>>> import os
>>> cwd = os.getcwd()
>>> uploadpath = os.path.join(cwd, 'testfiles')
>>> os.mkdir(uploadpath)
>>> pathsetting.value = uploadpath
And submit the form:
>>> browser.getControl(name='save').click()
We clean up the set directory path, as there might be some files be
copied some files from installation:
>>> files = os.listdir(uploadpath)
>>> for filename in files:
... if os.path.isdir(os.path.join(uploadpath, filename)):
... continue
... os.unlink(os.path.join(uploadpath, filename))
We also remove any existing 'accesscodes' subdir:
>>> import shutil
>>> for filename in files:
... if not os.path.isdir(os.path.join(uploadpath, filename)):
... continue
... if filename != 'accesscodes':
... continue
... shutil.rmtree(os.path.join(uploadpath, filename))
The new upload directory is now empty, except from the logs and other
standard dirs, which are created automatically:
>>> sorted(os.listdir(uploadpath))
['finished', 'jambdata', 'logs', 'unfinished']
Uploading files
---------------
Now we can upload files. Most interesting files might be CSV files,
that can be imported lateron. We create a CSV file containing faculty
descriptions:
>>> open('faculties.csv', 'wb').write(
... """code,title,title_prefix
... FA,Arts,Faculty
... FS,Sciences,Faculty
... """)
Now we can upload this file. To do this, we first go to the upload
page:
>>> browser.getLink('Upload CSV file').click()
and enter the appropriate data in the form:
>>> filewidget = browser.getControl(name='uploadfile:file')
>>> filewidget
A sidenote for developers: by marking the filewidget with the
``:file`` extension, we tell Zope to handle this field as a file
widget.
>>> import cStringIO
>>> filecontents = cStringIO.StringIO(
... open('faculties.csv', 'rb').read())
>>> filewidget.add_file(filecontents, 'text/plain', 'myfaculties.csv')
>>> browser.getControl(name='SUBMIT').click()
The file was indeed uploaded, with the current userid inserted:
>>> sorted(os.listdir(uploadpath))
['finished', 'jambdata', 'logs', 'myfaculties_zope.mgr.csv', 'unfinished']
We create and upload also a CSV file containing departments:
>>> open('departments.csv', 'wb').write(
... """code,title,title_prefix,faculty_code
... LIT,Literature,Department,FA
... SOC,Sociology,Department,FA
... PHY,Physics,Department,FS
... INF,Informatics,Department,FS
... MAT,Math,Department,FS
... """)
>>> browser.open('http://localhost/myuniversity/datacenter/upload')
>>> browser.getControl(name='uploadfile:file').add_file(
... cStringIO.StringIO(open('departments.csv', 'rb').read()),
... 'text/plain', 'mydepartments.csv')
>>> browser.getControl(name='SUBMIT').click()
We create and upload also a CSV file containing courses:
>>> open('courses.csv', 'wb').write(
... """code,level,title,passmark,credits,semester,faculty,department
... LI1,,Introduction to Literature I,40,2,1,FA,LIT
... LI2,,Introduction to Literature II,40,2,2,FA,LIT
... AN1,000,Analysis I,40,2,1,FS,MAT
... AN2,000,Analysis II,40,2,2,FS,MAT
... """)
>>> browser.open('http://localhost/myuniversity/datacenter/upload')
>>> browser.getControl(name='uploadfile:file').add_file(
... cStringIO.StringIO(open('courses.csv', 'rb').read()),
... 'text/plain', 'mycourses.csv')
>>> browser.getControl(name='SUBMIT').click()
We create and upload also a CSV file containing certificates:
>>> open('certificates.csv', 'wb').write(
... """code,title,faculty_code,department_code,study_mode,end_level,m_prefix,max_pass,start_level,application_category,review_state
... LBA,BACHELOR OF LITERATURE,FA,LIT,UG,ug_ft,500,LIT,30,100,basic,checked
... LMA,MASTER OF LITERATURE,FA,LIT,UG,ug_pt,500,LIT,30,100,cest,checked
... DME,DIPLOMA OF MATH,FS,MAT,DP,dp_ft,200,DME,30,100,cest,unchecked
... """)
>>> browser.open('http://localhost/myuniversity/datacenter/upload')
>>> browser.getControl(name='uploadfile:file').add_file(
... cStringIO.StringIO(open('certificates.csv', 'rb').read()),
... 'text/plain', 'mycertificates.csv')
>>> browser.getControl(name='SUBMIT').click()
We create and upload also a CSV file containing certificate courses:
>>> open('certcourses.csv', 'wb').write(
... """code,faculty_code,department_code,certificate_code,level,core_or_elective
... LI1,FA,LIT,LBA,100,True
... LI2,FA,LIT,LBA,200,True
... """)
>>> browser.open('http://localhost/myuniversity/datacenter/upload')
>>> browser.getControl(name='uploadfile:file').add_file(
... cStringIO.StringIO(open('certcourses.csv', 'rb').read()),
... 'text/plain', 'mycertcourses.csv')
>>> browser.getControl(name='SUBMIT').click()
Importing a CSV file
--------------------
The import of CSV files is described in batchprocessing.txt.
Clean up:
>>> import os
>>> import shutil
>>> shutil.rmtree(uploadpath)