source: main/waeup.sirp/trunk/src/waeup/sirp/students/tests/test_browser.py @ 6921

Last change on this file since 6921 was 6920, checked in by Henrik Bettermann, 13 years ago

Provide a getPaymentDetails function which requires a SessionConfiguration? object. This function is for demonstration and testing only.

  • Property svn:keywords set to Id
File size: 33.9 KB
Line 
1##
2## test_browser.py
3## Login : <uli@pu.smp.net>
4## Started on  Tue Mar 29 11:31:11 2011 Uli Fouquet
5## $Id: test_browser.py 6920 2011-10-22 05:15:30Z henrik $
6##
7## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22"""
23Test the student-related UI components.
24"""
25import shutil
26import tempfile
27import cStringIO
28from datetime import datetime
29from zope.component import createObject
30from zope.component.hooks import setSite, clearSite
31from zope.security.interfaces import Unauthorized
32from zope.testbrowser.testing import Browser
33from hurry.workflow.interfaces import IWorkflowInfo
34from waeup.sirp.testing import FunctionalLayer, FunctionalTestCase
35from waeup.sirp.app import University
36from waeup.sirp.configuration import SessionConfiguration
37from waeup.sirp.students.student import Student
38from waeup.sirp.university.faculty import Faculty
39from waeup.sirp.university.department import Department
40from waeup.sirp.interfaces import IUserAccount
41
42PH_LEN = 2059  # Length of placeholder file
43
44def lookup_submit_value(name, value, browser):
45    """Find a button with a certain value."""
46    for num in range(0, 100):
47        try:
48            button = browser.getControl(name=name, index=num)
49            if button.value.endswith(value):
50                return button
51        except IndexError:
52            break
53    return None
54
55class StudentsFullSetup(FunctionalTestCase):
56    # A test case that only contains a setup and teardown
57    #
58    # Complete setup for students handlings is rather complex and
59    # requires lots of things created before we can start. This is a
60    # setup that does all this, creates a university, creates PINs,
61    # etc.  so that we do not have to bother with that in different
62    # test cases.
63
64    layer = FunctionalLayer
65
66    def setUp(self):
67        super(StudentsFullSetup, self).setUp()
68
69        # Setup a sample site for each test
70        app = University()
71        self.dc_root = tempfile.mkdtemp()
72        app['datacenter'].setStoragePath(self.dc_root)
73
74        # Prepopulate the ZODB...
75        self.getRootFolder()['app'] = app
76        # we add the site immediately after creation to the
77        # ZODB. Catalogs and other local utilities are not setup
78        # before that step.
79        self.app = self.getRootFolder()['app']
80        # Set site here. Some of the following setup code might need
81        # to access grok.getSite() and should get our new app then
82        setSite(app)
83
84        # Set up SessionConfiguration object
85        configuration = SessionConfiguration()
86        configuration.academic_session = 2004
87        configuration.fee_1 = 20000
88        self.app['configuration'].addSessionConfiguration(configuration)
89
90        # Add student with subobjects
91        student = Student()
92        student.fullname = u'Anna Tester'
93        student.reg_number = u'123'
94        student.matric_number = u'234'
95        self.app['students'].addStudent(student)
96        self.student_id = student.student_id
97        self.student = self.app['students'][self.student_id]
98
99        # Set password
100        IUserAccount(
101            self.app['students'][self.student_id]).setPassword('spwd')
102
103        self.login_path = 'http://localhost/app/login'
104        self.container_path = 'http://localhost/app/students'
105        self.manage_container_path = self.container_path + '/@@manage'
106        self.add_student_path = self.container_path + '/addstudent'
107        self.student_path = self.container_path + '/' + self.student_id
108        self.manage_student_path = self.student_path + '/edit_base'
109        self.clearance_student_path = self.student_path + '/view_clearance'
110        self.personal_student_path = self.student_path + '/view_personal'
111        self.edit_clearance_student_path = self.student_path + '/edit_clearance'
112        self.edit_personal_student_path = self.student_path + '/edit_personal'
113
114        self.studycourse_student_path = self.student_path + '/studycourse'
115        self.payments_student_path = self.student_path + '/payments'
116        self.accommodation_student_path = self.student_path + '/accommodation'
117        self.history_student_path = self.student_path + '/history'
118
119        # Create 5 access codes with prefix'PWD'
120        pin_container = self.app['accesscodes']
121        pin_container.createBatch(
122            datetime.now(), 'some_userid', 'PWD', 9.99, 5)
123        pins = pin_container[pin_container.keys()[0]].values()
124        self.pwdpins = [x.representation for x in pins]
125        self.existing_pwdpin = self.pwdpins[0]
126        parts = self.existing_pwdpin.split('-')[1:]
127        self.existing_pwdseries, self.existing_pwdnumber = parts
128        # Create 5 access codes with prefix 'CLR'
129        pin_container.createBatch(
130            datetime.now(), 'some_userid', 'CLR', 9.99, 5)
131        pins = pin_container[pin_container.keys()[0]].values()
132        self.clrpins = [x.representation for x in pins]
133        self.existing_clrpin = self.clrpins[0]
134        self.existing_clrpin
135        parts = self.existing_clrpin.split('-')[1:]
136        self.existing_clrseries, self.existing_clrnumber = parts
137
138        # Populate university
139        self.certificate = createObject('waeup.Certificate')
140        self.certificate.code = u'CERT1'
141        self.certificate.application_category = 'basic'
142        self.certificate.study_mode = 'ug_ft'
143        self.certificate.start_level = 100
144        self.certificate.end_level = 500
145        self.app['faculties']['fac1'] = Faculty()
146        self.app['faculties']['fac1']['dep1'] = Department()
147        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
148            self.certificate)
149        self.course = createObject('waeup.Course')
150        self.course.code = 'COURSE1'
151        self.course.semester = 1
152        self.course.credits = 10
153        self.course.passmark = 40
154        self.app['faculties']['fac1']['dep1'].courses.addCourse(
155            self.course)
156        self.app['faculties']['fac1']['dep1'].certificates['CERT1'].addCourseRef(
157            self.course, level=100)
158
159        # Set study course attributes of test student
160        self.student['studycourse'].certificate = self.certificate
161        self.student['studycourse'].current_session = 2004
162        self.student['studycourse'].current_verdict = 'A'
163        self.student['studycourse'].current_level = 100
164
165        # Put the prepopulated site into test ZODB and prepare test
166        # browser
167        self.browser = Browser()
168        self.browser.handleErrors = False
169
170    def tearDown(self):
171        super(StudentsFullSetup, self).tearDown()
172        clearSite()
173        shutil.rmtree(self.dc_root)
174
175
176
177class StudentsContainerUITests(StudentsFullSetup):
178    # Tests for StudentsContainer class views and pages
179
180    layer = FunctionalLayer
181
182    def test_anonymous_access(self):
183        # Anonymous users can't access students containers
184        self.assertRaises(
185            Unauthorized, self.browser.open, self.container_path)
186        self.assertRaises(
187            Unauthorized, self.browser.open, self.manage_container_path)
188        return
189
190    def test_manage_access(self):
191        # Managers can access the view page of students
192        # containers and can perform actions
193        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
194        self.browser.open(self.container_path)
195        self.assertEqual(self.browser.headers['Status'], '200 Ok')
196        self.assertEqual(self.browser.url, self.container_path)
197        self.browser.getLink("Manage student section").click()
198        self.assertEqual(self.browser.headers['Status'], '200 Ok')
199        self.assertEqual(self.browser.url, self.manage_container_path)
200        return
201
202    def test_add_search_delete_students(self):
203        # Managers can add search and remove students
204        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
205        self.browser.open(self.manage_container_path)
206        self.browser.getLink("Add student").click()
207        self.assertEqual(self.browser.headers['Status'], '200 Ok')
208        self.assertEqual(self.browser.url, self.add_student_path)
209        self.browser.getControl(name="form.fullname").value = 'Bob Tester'
210        self.browser.getControl("Create student record").click()
211        self.assertTrue('Student record created' in self.browser.contents)
212
213        # Registration and matric numbers must be unique
214        self.browser.getLink("Manage").click()
215        self.browser.getControl(name="form.reg_number").value = '123'
216        self.browser.getControl("Save").click()
217        self.assertMatches('...Registration number exists...',
218                           self.browser.contents)
219        self.browser.getControl(name="form.reg_number").value = '789'
220        self.browser.getControl(name="form.matric_number").value = '234'
221        self.browser.getControl("Save").click()
222        self.assertMatches('...Matriculation number exists...',
223                           self.browser.contents)
224
225        self.browser.open(self.container_path)
226        self.browser.getControl("Search").click()
227        self.assertTrue('Empty search string' in self.browser.contents)
228        self.browser.getControl(name="searchtype").value = ['student_id']
229        self.browser.getControl(name="searchterm").value = self.student_id
230        self.browser.getControl("Search").click()
231        self.assertTrue('Anna Tester' in self.browser.contents)
232
233        self.browser.open(self.manage_container_path)
234        self.browser.getControl("Search").click()
235        self.assertTrue('Empty search string' in self.browser.contents)
236        self.browser.getControl(name="searchtype").value = ['fullname']
237        self.browser.getControl(name="searchterm").value = 'Anna Tester'
238        self.browser.getControl("Search").click()
239        self.assertTrue('Anna Tester' in self.browser.contents)
240        # The old searchterm will be used again
241        self.browser.getControl("Search").click()
242        self.assertTrue('Anna Tester' in self.browser.contents)
243
244        ctrl = self.browser.getControl(name='entries')
245        ctrl.getControl(value=self.student_id).selected = True
246        self.browser.getControl("Remove selected", index=0).click()
247        self.assertTrue('Successfully removed' in self.browser.contents)
248        self.browser.getControl(name="searchtype").value = ['student_id']
249        self.browser.getControl(name="searchterm").value = self.student_id
250        self.browser.getControl("Search").click()
251        self.assertTrue('No student found' in self.browser.contents)
252
253        self.browser.open(self.container_path)
254        self.browser.getControl(name="searchtype").value = ['student_id']
255        self.browser.getControl(name="searchterm").value = self.student_id
256        self.browser.getControl("Search").click()
257        self.assertTrue('No student found' in self.browser.contents)
258        return
259
260class StudentUITests(StudentsFullSetup):
261    # Tests for Student class views and pages
262
263    layer = FunctionalLayer
264
265    def test_manage_access(self):
266        # Managers can access the pages of students
267        # and can perform actions
268        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
269
270        self.browser.open(self.student_path)
271        self.assertEqual(self.browser.headers['Status'], '200 Ok')
272        self.assertEqual(self.browser.url, self.student_path)
273        self.browser.getLink("Manage").click()
274        self.assertEqual(self.browser.headers['Status'], '200 Ok')
275        self.assertEqual(self.browser.url, self.manage_student_path)
276        # Managers can edit base data and fire transitions
277        self.browser.getControl(name="transition").value = ['admit']
278        self.browser.getControl(name="form.fullname").value = 'John Tester'
279        self.browser.getControl(name="form.reg_number").value = '345'
280        self.browser.getControl(name="password").value = 'secret'
281        self.browser.getControl(name="control_password").value = 'secret'
282        self.browser.getControl("Save").click()
283        self.assertMatches('...Form has been saved...',
284                           self.browser.contents)
285        self.browser.open(self.student_path)
286        self.browser.getLink("Clearance Data").click()
287        self.assertEqual(self.browser.headers['Status'], '200 Ok')
288        self.assertEqual(self.browser.url, self.clearance_student_path)
289        self.browser.getLink("Manage").click()
290        self.assertEqual(self.browser.headers['Status'], '200 Ok')
291        self.assertEqual(self.browser.url, self.edit_clearance_student_path)
292        self.browser.getControl(name="form.date_of_birth").value = '09/10/1961'
293        self.browser.getControl("Save").click()
294        self.assertMatches('...Form has been saved...',
295                           self.browser.contents)
296
297        self.browser.open(self.student_path)
298        self.browser.getLink("Personal Data").click()
299        self.assertEqual(self.browser.headers['Status'], '200 Ok')
300        self.assertEqual(self.browser.url, self.personal_student_path)
301        self.browser.getLink("Manage").click()
302        self.assertEqual(self.browser.headers['Status'], '200 Ok')
303        self.assertEqual(self.browser.url, self.edit_personal_student_path)
304        self.browser.getControl("Save").click()
305        self.assertMatches('...Form has been saved...',
306                           self.browser.contents)
307
308        # Managers can browse all subobjects
309        self.browser.open(self.student_path)
310        self.browser.getLink("Payments").click()
311        self.assertEqual(self.browser.headers['Status'], '200 Ok')
312        self.assertEqual(self.browser.url, self.payments_student_path)
313        self.browser.open(self.student_path)
314        self.browser.getLink("Accommodation").click()
315        self.assertEqual(self.browser.headers['Status'], '200 Ok')
316        self.assertEqual(self.browser.url, self.accommodation_student_path)
317        self.browser.open(self.student_path)
318        self.browser.getLink("History").click()
319        self.assertEqual(self.browser.headers['Status'], '200 Ok')
320        self.assertEqual(self.browser.url, self.history_student_path)
321        self.assertMatches('...Student admitted by zope.mgr...',
322                           self.browser.contents)
323        return
324
325    def test_manage_course_lists(self):
326        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
327        self.browser.open(self.student_path)
328        self.browser.getLink("Study Course").click()
329        self.assertEqual(self.browser.headers['Status'], '200 Ok')
330        self.assertEqual(self.browser.url, self.studycourse_student_path)
331        self.browser.getLink("Manage").click()
332        self.assertTrue('Manage study course' in self.browser.contents)
333        # Before we can select a level, the certificate must be selected and saved
334        self.browser.getControl(name="form.certificate").value = ['CERT1']
335        self.browser.getControl(name="form.current_session").value = ['2004']
336        self.browser.getControl(name="form.current_verdict").value = ['A']
337        self.browser.getControl("Save").click()
338        # Now we can save also the current level which depends on start and end
339        # level of the certificate
340        self.browser.getControl(name="form.current_level").value = ['100']
341        self.browser.getControl("Save").click()
342        # Managers can add and remove any study level (course list)
343        self.browser.getControl(name="addlevel").value = ['100']
344        self.browser.getControl("Add study level").click()
345        self.assertMatches('...<span>100</span>...', self.browser.contents)
346        self.browser.getControl("Add study level").click()
347        self.assertMatches('...This level exists...', self.browser.contents)
348        self.browser.getControl("Remove selected").click()
349        self.assertMatches('...No study level selected...', self.browser.contents)
350        self.browser.getControl(name="val_id").value = ['100']
351        self.browser.getControl("Remove selected").click()
352        self.assertMatches('...Successfully removed...', self.browser.contents)
353        # Add level again
354        self.browser.getControl(name="addlevel").value = ['100']
355        self.browser.getControl("Add study level").click()
356        self.browser.getControl(name="addlevel").value = ['100']
357
358        # Managers can view and manage course lists
359        self.browser.getLink("100").click()
360        self.assertMatches('...: Study Level 100 (Year 1)...', self.browser.contents)
361        self.browser.getLink("Manage").click()
362        self.browser.getControl(name="form.level_session").value = ['2002']
363        self.browser.getControl("Save").click()
364        self.browser.getControl("Remove selected").click()
365        self.assertMatches('...No ticket selected...', self.browser.contents)
366        ctrl = self.browser.getControl(name='val_id')
367        ctrl.getControl(value='COURSE1').selected = True
368        self.browser.getControl("Remove selected", index=0).click()
369        self.assertTrue('Successfully removed' in self.browser.contents)
370        self.browser.getControl("Add course ticket").click()
371        self.browser.getControl(name="form.course").value = ['COURSE1']
372        self.browser.getControl("Add course ticket").click()
373        self.assertTrue('Successfully added' in self.browser.contents)
374        self.browser.getControl("Add course ticket").click()
375        self.browser.getControl(name="form.course").value = ['COURSE1']
376        self.browser.getControl("Add course ticket").click()
377        self.assertTrue('The ticket exists' in self.browser.contents)
378        self.browser.getControl("Cancel").click()
379        self.browser.getLink("COURSE1").click()
380        self.browser.getLink("Manage").click()
381        self.browser.getControl(name="form.score").value = '10'
382        self.browser.getControl("Save").click()
383        self.assertTrue('Form has been saved' in self.browser.contents)
384        return
385
386    def test_manage_workflow(self):
387        # Managers can pass through the whole workflow
388        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
389        student = self.app['students'][self.student_id]
390        self.browser.open(self.manage_student_path)
391        self.assertTrue(student.clearance_locked)
392        self.browser.getControl(name="transition").value = ['admit']
393        self.browser.getControl("Save").click()
394        self.assertTrue(student.clearance_locked)
395        self.browser.getControl(name="transition").value = ['start_clearance']
396        self.browser.getControl("Save").click()
397        self.assertFalse(student.clearance_locked)
398        self.browser.getControl(name="transition").value = ['request_clearance']
399        self.browser.getControl("Save").click()
400        self.assertTrue(student.clearance_locked)
401        self.browser.getControl(name="transition").value = ['clear']
402        self.browser.getControl("Save").click()
403        self.browser.getControl(name="transition").value = ['pay_first_school_fee']
404        self.browser.getControl("Save").click()
405        self.browser.getControl(name="transition").value = ['reset6']
406        self.browser.getControl("Save").click()
407        # In state returning the pay_school_fee transition triggers some
408        # changes of attributes
409        self.browser.getControl(name="transition").value = ['pay_school_fee']
410        self.browser.getControl("Save").click()
411        self.assertEqual(student['studycourse'].current_session, 2005) # +1
412        self.assertEqual(student['studycourse'].current_level, 200) # +100
413        self.assertEqual(student['studycourse'].current_verdict, '0') # 0 = not set
414        self.assertEqual(student['studycourse'].previous_verdict, 'A')
415        self.browser.getControl(name="transition").value = ['register_courses']
416        self.browser.getControl("Save").click()
417        self.browser.getControl(name="transition").value = ['validate_courses']
418        self.browser.getControl("Save").click()
419        self.browser.getControl(name="transition").value = ['return']
420        self.browser.getControl("Save").click()
421        return
422
423    def test_manage_import(self):
424        # Managers can import student data files
425        datacenter_path = 'http://localhost/app/datacenter'
426        # Prepare a csv file for students
427        open('students.csv', 'wb').write(
428"""firstname,lastname,fullname,reg_number,date_of_birth,matric_number
429Aaren,Pieri,Aaren Pieri,1,1990-01-02,100000
430Claus,Finau,Claus Finau,2,1990-01-03,100001
431Brit,Berson,Brit Berson,3,1990-01-04,100001
432""")
433        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
434        self.browser.open(datacenter_path)
435        self.browser.getLink('Upload CSV file').click()
436        filecontents = cStringIO.StringIO(open('students.csv', 'rb').read())
437        filewidget = self.browser.getControl(name='uploadfile:file')
438        filewidget.add_file(filecontents, 'text/plain', 'students.csv')
439        self.browser.getControl(name='SUBMIT').click()
440        self.browser.getLink('Batch processing').click()
441        button = lookup_submit_value(
442            'select', 'students_zope.mgr.csv', self.browser)
443        button.click()
444        importerselect = self.browser.getControl(name='importer')
445        modeselect = self.browser.getControl(name='mode')
446        importerselect.getControl('Student Importer').selected = True
447        modeselect.getControl(value='create').selected = True
448        self.browser.getControl('Proceed to step 3...').click()
449        self.assertTrue('Header fields OK' in self.browser.contents)
450        self.browser.getControl('Perform import...').click()
451        self.assertTrue('Processing of 1 rows failed' in self.browser.contents)
452        self.assertTrue('Successfully processed 2 rows' in self.browser.contents)
453        self.assertTrue('Batch processing finished' in self.browser.contents)
454        open('studycourses.csv', 'wb').write(
455"""reg_number,matric_number,certificate,current_session,current_level
4561,,CERT1,2008,100
457,100001,CERT1,2008,100
458,100002,CERT1,2008,100
459""")
460        self.browser.open(datacenter_path)
461        self.browser.getLink('Upload CSV file').click()
462        filecontents = cStringIO.StringIO(open('studycourses.csv', 'rb').read())
463        filewidget = self.browser.getControl(name='uploadfile:file')
464        filewidget.add_file(filecontents, 'text/plain', 'studycourses.csv')
465        self.browser.getControl(name='SUBMIT').click()
466        self.browser.getLink('Batch processing').click()
467        button = lookup_submit_value(
468            'select', 'studycourses_zope.mgr.csv', self.browser)
469        button.click()
470        importerselect = self.browser.getControl(name='importer')
471        modeselect = self.browser.getControl(name='mode')
472        importerselect.getControl(
473            'StudentStudyCourse Importer (update only)').selected = True
474        modeselect.getControl(value='create').selected = True
475        self.browser.getControl('Proceed to step 3...').click()
476        self.assertTrue('Update mode only' in self.browser.contents)
477        self.browser.getControl('Proceed to step 3...').click()
478        self.assertTrue('Header fields OK' in self.browser.contents)
479        self.browser.getControl('Perform import...').click()
480        self.assertTrue('Processing of 1 rows failed' in self.browser.contents)
481        self.assertTrue('Successfully processed 2 rows' in self.browser.contents)
482
483    def test_student_change_password(self):
484        # Students can change the password
485        self.browser.open(self.login_path)
486        self.browser.getControl(name="form.login").value = self.student_id
487        self.browser.getControl(name="form.password").value = 'spwd'
488        self.browser.getControl("Login").click()
489        self.assertEqual(self.browser.url, self.student_path)
490        self.assertTrue('You logged in' in self.browser.contents)
491        # Change password
492        self.browser.getLink("Change password").click()
493        self.browser.getControl(name="form.password").value = 'new_password'
494        self.browser.getControl(
495            name="form.password_repeat").value = 'new_passssword'
496        self.browser.getControl("Save").click()
497        self.assertTrue('passwords do not match' in self.browser.contents)
498        self.browser.getControl(name="form.password").value = 'new_password'
499        self.browser.getControl(
500            name="form.password_repeat").value = 'new_password'
501        self.browser.getControl("Save").click()
502        self.assertTrue('Form has been saved' in self.browser.contents)
503        # We are still logged in. Changing the password hasn't thrown us out.
504        self.browser.getLink("My Data").click()
505        self.assertEqual(self.browser.url, self.student_path)
506        # We can logout
507        self.browser.getLink("Logout").click()
508        self.assertTrue('You have been logged out' in self.browser.contents)
509        self.assertEqual(self.browser.url, 'http://localhost/app')
510        # We can login again with the new password
511        self.browser.getLink("Login").click()
512        self.browser.open(self.login_path)
513        self.browser.getControl(name="form.login").value = self.student_id
514        self.browser.getControl(name="form.password").value = 'new_password'
515        self.browser.getControl("Login").click()
516        self.assertEqual(self.browser.url, self.student_path)
517        self.assertTrue('You logged in' in self.browser.contents)
518        return
519
520    def test_setpassword(self):
521        # Set password for first-time access
522        student = Student()
523        student.reg_number = u'123456'
524        student.fullname = u'Klaus Tester'
525        self.app['students'].addStudent(student)
526        setpassword_path = 'http://localhost/app/setpassword'
527        student_path = 'http://localhost/app/students/%s' % student.student_id
528        self.browser.open(setpassword_path)
529        self.browser.getControl(name="ac_series").value = self.existing_pwdseries
530        self.browser.getControl(name="ac_number").value = self.existing_pwdnumber
531        self.browser.getControl(name="reg_number").value = '223456'
532        self.browser.getControl("Show").click()
533        self.assertMatches('...No student found...',
534                           self.browser.contents)
535        self.browser.getControl(name="reg_number").value = '123456'
536        self.browser.getControl(name="ac_number").value = '999999'
537        self.browser.getControl("Show").click()
538        self.assertMatches('...Access code is invalid...',
539                           self.browser.contents)
540        self.browser.getControl(name="ac_number").value = self.existing_pwdnumber
541        self.browser.getControl("Show").click()
542        self.assertMatches('...Password has been set. Your Student Id is...',
543                           self.browser.contents)
544        self.browser.getControl("Show").click()
545        self.assertMatches(
546            '...Password has already been set. Your Student Id is...',
547            self.browser.contents)
548        existing_pwdpin = self.pwdpins[1]
549        parts = existing_pwdpin.split('-')[1:]
550        existing_pwdseries, existing_pwdnumber = parts
551        self.browser.getControl(name="ac_series").value = existing_pwdseries
552        self.browser.getControl(name="ac_number").value = existing_pwdnumber
553        self.browser.getControl(name="reg_number").value = '123456'
554        self.browser.getControl("Show").click()
555        self.assertMatches(
556            '...You are using the wrong Access Code...',
557            self.browser.contents)
558        # The student can login with the new credentials
559        self.browser.open(self.login_path)
560        self.browser.getControl(name="form.login").value = student.student_id
561        self.browser.getControl(
562            name="form.password").value = self.existing_pwdnumber
563        self.browser.getControl("Login").click()
564        self.assertEqual(self.browser.url, student_path)
565        self.assertTrue('You logged in' in self.browser.contents)
566        return
567
568    def test_student_access(self):
569        # Students can access their own objects
570        # and can perform actions
571        student = self.app['students'][self.student_id]
572        IWorkflowInfo(student).fireTransition('admit')
573        self.browser.open(self.login_path)
574        self.browser.getControl(name="form.login").value = self.student_id
575        self.browser.getControl(name="form.password").value = 'spwd'
576        self.browser.getControl("Login").click()
577        # Student can view the clearance data
578        self.browser.getLink("Clearance Data").click()
579        # Student can't open clearance edit form before starting clearance
580        self.browser.open(self.student_path + '/cedit')
581        self.assertMatches('...The requested form is locked...',
582                           self.browser.contents)
583        self.browser.getLink("Clearance Data").click()
584        self.browser.getLink("Start clearance").click()
585        self.browser.getControl(name="ac_series").value = '3'
586        self.browser.getControl(name="ac_number").value = '4444444'
587        self.browser.getControl("Start clearance now").click()
588        self.assertMatches('...Access code is invalid...',
589                           self.browser.contents)
590        self.browser.getControl(name="ac_series").value = self.existing_clrseries
591        self.browser.getControl(name="ac_number").value = self.existing_clrnumber
592        self.browser.getControl("Start clearance now").click()
593        self.assertMatches('...Clearance process has been started...',
594                           self.browser.contents)
595        self.browser.getControl(name="form.date_of_birth").value = '09/10/1961'
596        self.browser.getControl("Save", index=0).click()
597        # Student can view the clearance data
598        self.browser.getLink("Clearance Data").click()
599        # and go back to the edit form
600        self.browser.getLink("Edit").click()
601        self.browser.getControl("Save and request clearance").click()
602        self.browser.getControl(name="ac_series").value = self.existing_clrseries
603        self.browser.getControl(name="ac_number").value = self.existing_clrnumber
604        self.browser.getControl("Request clearance now").click()
605        self.assertMatches('...Clearance has been requested...',
606                           self.browser.contents)
607        # Student can't reopen clearance form after requesting clearance
608        self.browser.open(self.student_path + '/cedit')
609        self.assertMatches('...The requested form is locked...',
610                           self.browser.contents)
611        # Student can't add study level if not in state 'school fee paid'
612        self.browser.open(self.student_path + '/studycourse/add')
613        self.assertMatches('...The requested form is locked...',
614                           self.browser.contents)
615        # ... and must be transferred first
616        IWorkflowInfo(student).fireTransition('clear')
617        IWorkflowInfo(student).fireTransition('pay_first_school_fee')
618        # Now students can add the current study level
619        self.browser.getLink("Study Course").click()
620        self.browser.getLink("Add course list").click()
621        self.assertMatches('...Add current level 100 (Year 1)...',
622                           self.browser.contents)
623        self.browser.getControl("Create course list now").click()
624        self.browser.getLink("100").click()
625        self.browser.getLink("Add and remove courses").click()
626        self.browser.getControl("Add course ticket").click()
627        self.browser.getControl(name="form.course").value = ['COURSE1']
628        self.browser.getControl("Add course ticket").click()
629        self.assertMatches('...The ticket exists...',
630                           self.browser.contents)
631        self.student['studycourse'].current_level = 200
632        self.browser.getLink("Study Course").click()
633        self.browser.getLink("Add course list").click()
634        self.assertMatches('...Add current level 200 (Year 2)...',
635                           self.browser.contents)
636        self.browser.getControl("Create course list now").click()
637        self.browser.getLink("200").click()
638        self.browser.getLink("Add and remove courses").click()
639        self.browser.getControl("Add course ticket").click()
640        self.browser.getControl(name="form.course").value = ['COURSE1']
641        self.browser.getControl("Add course ticket").click()
642        self.assertMatches('...Successfully added COURSE1...',
643                           self.browser.contents)
644        self.browser.getControl("Remove selected", index=0).click()
645        self.assertTrue('No ticket selected' in self.browser.contents)
646        ctrl = self.browser.getControl(name='val_id')
647        ctrl.getControl(value='COURSE1').selected = True
648        self.browser.getControl("Remove selected", index=0).click()
649        self.assertTrue('Successfully removed' in self.browser.contents)
650        self.browser.getControl("Register course list").click()
651        self.assertTrue('Course list has been registered' in self.browser.contents)
652        self.assertEqual(self.student.state, 'courses registered')
653        return
654
655    def test_manage_payments(self):
656        # Managers can add and remove online payment tickets
657        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
658        self.browser.open(self.payments_student_path)
659        self.browser.getLink("Manage").click()
660        self.browser.getControl("Add online payment ticket").click()
661        self.browser.getControl("Create ticket").click()
662        self.assertMatches('...ticket created...',
663                           self.browser.contents)
664        ctrl = self.browser.getControl(name='val_id')
665        value = ctrl.options[0]
666        self.browser.getLink(value).click()
667        self.assertMatches('...Amount Authorized...',
668                           self.browser.contents)
669        self.browser.open(self.payments_student_path)
670        self.browser.getLink('Manage').click()
671        self.browser.getControl("Remove selected").click()
672        self.assertMatches('...No payment selected...', self.browser.contents)
673        ctrl = self.browser.getControl(name='val_id')
674        value = ctrl.options[0]
675        ctrl.getControl(value=value).selected = True
676        self.browser.getControl("Remove selected", index=0).click()
677        self.assertTrue('Successfully removed' in self.browser.contents)
Note: See TracBrowser for help on using the repository browser.