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

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

Do not setup SessionConfiguration? object in StudentsFullSetup?. We need the setUp method also in customization packages and ISessionConfiguration will be customized there.

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