source: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/students/tests/test_browser.py

Last change on this file was 17866, checked in by Henrik Bettermann, 3 months ago

Implement final clearance.

  • Property svn:keywords set to Id
File size: 27.4 KB
RevLine 
[8862]1## $Id: test_browser.py 17866 2024-08-01 11:02:51Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18import os
19import shutil
20import tempfile
[13623]21from time import time
[9562]22from datetime import datetime, timedelta
[8862]23from StringIO import StringIO
[9041]24from hurry.workflow.interfaces import IWorkflowState, IWorkflowInfo
[8862]25from zope.component.hooks import setSite, clearSite
26from zope.component import getUtility, createObject
27from zope.interface import verify
[13620]28from zope.securitypolicy.interfaces import IPrincipalRoleManager
[8862]29from waeup.kofa.app import University
[9239]30from waeup.kofa.students.tests.test_browser import (
31    StudentsFullSetup, SAMPLE_IMAGE)
[8862]32from waeup.kofa.testing import FunctionalTestCase
33from waeup.kofa.interfaces import (
34    IExtFileStore, IFileStoreNameChooser)
[12417]35from waeup.kofa.schoolgrades import ResultEntry
[8862]36from waeup.kofa.students.batching import StudentProcessor
37from waeup.kofa.students.interfaces import IStudentsUtils
[13623]38from waeup.kofa.browser.tests.test_pdf import samples_dir
[15351]39from waeup.kofa.tests.test_authentication import SECRET
[8863]40from kofacustom.nigeria.students.batching import NigeriaStudentProcessor
[8862]41from kofacustom.nigeria.testing import FunctionalLayer
[12417]42from kofacustom.nigeria.utils.utils import NigeriaKofaUtils
[8862]43from kofacustom.nigeria.students.interfaces import (
[8863]44    INigeriaStudentStudyCourse, INigeriaStudent,
45    INigeriaStudentStudyLevel, INigeriaCourseTicket)
[8862]46
47
48STUDENT_SAMPLE_DATA = open(
49    os.path.join(os.path.dirname(__file__), 'sample_student_data.csv'),
50    'rb').read()
51
52STUDENT_HEADER_FIELDS = STUDENT_SAMPLE_DATA.split(
53    '\n')[0].split(',')
54
55class StudentProcessorTest(FunctionalTestCase):
56    """Perform some batching tests.
57    """
58
59    layer = FunctionalLayer
60
61    def setUp(self):
62        super(StudentProcessorTest, self).setUp()
63        # Setup a sample site for each test
64        app = University()
65        self.dc_root = tempfile.mkdtemp()
66        app['datacenter'].setStoragePath(self.dc_root)
67
68        # Prepopulate the ZODB...
69        self.getRootFolder()['app'] = app
70        # we add the site immediately after creation to the
71        # ZODB. Catalogs and other local utilities are not setup
72        # before that step.
73        self.app = self.getRootFolder()['app']
74        # Set site here. Some of the following setup code might need
75        # to access grok.getSite() and should get our new app then
76        setSite(app)
77
78        self.processor_base = StudentProcessor()
[8863]79        self.processor = NigeriaStudentProcessor()
[8862]80        self.workdir = tempfile.mkdtemp()
81        self.csv_file = os.path.join(self.workdir, 'sample_student_data.csv')
82        open(self.csv_file, 'wb').write(STUDENT_SAMPLE_DATA)
83
84    def tearDown(self):
85        super(StudentProcessorTest, self).tearDown()
86        shutil.rmtree(self.workdir)
87        shutil.rmtree(self.dc_root)
88        clearSite()
89        return
90
91    def test_import(self):
92        num, num_warns, fin_file, fail_file = self.processor.doImport(
93            self.csv_file, STUDENT_HEADER_FIELDS)
94        #print open(fail_file).read()
95        self.assertEqual(num_warns,0)
96        assert len(self.app['students'].keys()) == 3
[11054]97        # Also fst_sit_results have been properly imported (tested only here!)
98        self.assertEqual(
99            self.app['students']['K1000000'].fst_sit_results[0].__dict__,
100            {'grade': 'A1', 'subject': 'visual_art'})
101        self.assertEqual(
102            self.app['students']['K1000000'].fst_sit_results[1].__dict__,
103            {'grade': 'C6', 'subject': 'applied_electricity'})
[8862]104        shutil.rmtree(os.path.dirname(fin_file))
105
106
107class StudentUITests(StudentsFullSetup):
108    """Tests for customized student class views and pages
109    """
110
111    layer = FunctionalLayer
112
[9041]113    def setUp(self):
114        super(StudentUITests, self).setUp()
115
[8862]116    def test_classes(self):
117        # Let's see if objects created in the customized
118        # portal really implement the customized interfaces
[8863]119        verify.verifyObject(INigeriaStudent, self.student)
[8862]120        verify.verifyObject(
[8863]121            INigeriaStudentStudyCourse, self.student['studycourse'])
[8862]122        studylevel = createObject(u'waeup.StudentStudyLevel')
[8863]123        verify.verifyObject(INigeriaStudentStudyLevel, studylevel)
[8862]124        ticket = createObject(u'waeup.CourseTicket')
[8863]125        verify.verifyObject(INigeriaCourseTicket, ticket)
[8862]126        IWorkflowState(self.student).setState('returning')
127        # Let's see if next_session_allowed works as expected
128        # A, ug_ft, 100
129        self.assertTrue(self.student['studycourse'].next_session_allowed)
[9356]130        # Zero, ug_ft, 100
131        self.student['studycourse'].current_verdict = '0' # Zero!
[8862]132        self.assertTrue(self.student['studycourse'].next_session_allowed)
[9356]133        # Zero, ug_ft, 200
[8862]134        self.student['studycourse'].current_level = 200
135        self.assertFalse(self.student['studycourse'].next_session_allowed)
[9356]136        # Zero, de_ft, 200
[8862]137        self.student['studycourse'].certificate.study_mode = 'de_ft'
138        self.assertTrue(self.student['studycourse'].next_session_allowed)
[9356]139        # Zero, ph_ft, 300
[8862]140        self.student['studycourse'].certificate.study_mode = 'ph_ft'
141        self.student['studycourse'].current_level = 300
142        self.assertTrue(self.student['studycourse'].next_session_allowed)
[9356]143        # Zero, ph_ft, 400
[8862]144        self.student['studycourse'].current_level = 400
145        self.assertFalse(self.student['studycourse'].next_session_allowed)
146
147        # Now we convert the certificate into a postgraduate certificate
148        IWorkflowState(self.student).setState('school fee paid')
149        self.certificate.study_mode = 'pg_ft'
150        # ... and voila next session registration is allowed
151        self.assertTrue(self.student['studycourse'].next_session_allowed)
152
153    def test_manage_access(self):
[9379]154        self.student.nationality = u'DE'
[8862]155        # Managers can access the pages of students
156        # and can perform actions
157        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
158        # The student created in the base package is an ug student
159        self.browser.open(self.student_path)
160        self.browser.getLink("Clearance Data").click()
161        self.assertEqual(self.browser.headers['Status'], '200 Ok')
162        self.assertEqual(self.browser.url, self.clearance_path)
163        self.browser.getLink("Manage").click()
164        self.assertEqual(self.browser.headers['Status'], '200 Ok')
165        self.assertEqual(self.browser.url, self.manage_clearance_path)
166        self.browser.getControl(name="form.date_of_birth").value = '09/10/1961'
167        self.browser.getControl("Save").click()
168        self.assertMatches('...Form has been saved...',
169                           self.browser.contents)
170        self.assertMatches('...First Sitting Record...',
171                           self.browser.contents)
172        # Managers can open clearance slip of ug students
[9472]173        self.browser.open(self.student_path + '/clearance_slip.pdf')
[8862]174        self.assertEqual(self.browser.headers['Status'], '200 Ok')
175        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
176        # There is no pg field in the clearance form
177        self.assertFalse('Second Higher Education Record'
178            in self.browser.contents)
179        # Now we change the study mode ...
180        self.certificate.study_mode = 'pg_ft'
181        self.browser.open(self.clearance_path)
182        # ... and additional pg clearance fields appear
183        self.assertMatches('...Second Higher Education Record...',
184                           self.browser.contents)
185        # But also fields from the ug form are displayed
186        self.assertMatches('...First Sitting Record...',
187                           self.browser.contents)
188        # Managers can open clearance slip of pg students
[9472]189        self.browser.open(self.student_path + '/clearance_slip.pdf')
[8862]190        self.assertEqual(self.browser.headers['Status'], '200 Ok')
191        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
[9564]192        # Managers can edit personal data. No fields are required.
193        self.browser.open(self.manage_personal_path)
194        self.browser.getControl("Save").click()
195        self.assertMatches('...Form has been saved...',
196                           self.browser.contents)
[8862]197
[12417]198    def test_logging(self):
199        self.student.nationality = u'DE'
200        valid_subj = NigeriaKofaUtils().EXAM_SUBJECTS_DICT.keys()[0]
201        valid_grade = NigeriaKofaUtils().EXAM_GRADES[0][0]
202        result_entry = ResultEntry(valid_subj, valid_grade)
203        self.student.fst_sit_results = [result_entry,]
204        # Managers can access the pages of students
205        # and can perform actions
206        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
207        # The student created in the base package is an ug student
208        self.browser.open(self.student_path)
209        self.browser.getLink("Clearance Data").click()
210        self.browser.getLink("Manage").click()
211        self.browser.getControl("Save").click()
212        logfile = os.path.join(
213            self.app['datacenter'].storage, 'logs', 'students.log')
214        logcontent = open(logfile).read()
215        self.assertFalse('saved: fst_sit_results' in logcontent)
216
[8862]217    def test_student_access(self):
218        # Students can edit clearance data
219        IWorkflowState(self.student).setState('cleared')
220        self.browser.open(self.login_path)
221        self.browser.getControl(name="form.login").value = self.student_id
222        self.browser.getControl(name="form.password").value = 'spwd'
223        self.browser.getControl("Login").click()
224        # Even in state admitted students can't change the portait if
225        # application slip exists.
226        IWorkflowState(self.student).setState('admitted')
227        self.browser.open(self.student_path)
228        self.assertTrue('Change portrait' in self.browser.contents)
229        file_store = getUtility(IExtFileStore)
230        applicant_slip = 'My application slip'
231        file_id = IFileStoreNameChooser(self.student).chooseName(
232            attr="application_slip.pdf")
233        file_store.createFile(file_id, StringIO(applicant_slip))
234        self.browser.open(self.student_path)
235        self.assertFalse('Change portrait' in self.browser.contents)
236        self.browser.open(self.student_path + '/change_portrait')
237        self.assertTrue('The requested form is locked' in self.browser.contents)
[9041]238
[9379]239        # Student can view and edit clearance data if clearance has started ...
[9041]240        IWorkflowInfo(self.student).fireTransition('start_clearance')
[9536]241        self.student.officer_comment = u'Fill properly'
[8862]242        self.browser.getLink("Clearance Data").click()
[9536]243        self.assertTrue("Officer's Comment" in self.browser.contents)
244        # Students can't edit officer's comment
[8862]245        self.browser.getLink("Edit").click()
[9536]246        self.assertFalse("Officer's Comment" in self.browser.contents)
[8862]247        self.assertTrue('Save' in self.browser.contents)
[9379]248        # ... and request clearance if nationality field has been filled.
249        self.browser.getControl("Save and request clearance").click()
250        self.assertMatches('...Required input is missing...',
251                           self.browser.contents)
252        self.student.nationality = u'DE'
253        self.browser.open(self.edit_clearance_path)
254        self.browser.getControl("Save and request clearance").click()
255        self.assertMatches('...Clearance has been requested...',
256                           self.browser.contents)
[9041]257
[9564]258        # Students can edit personal data. Some fields are required.
259        self.browser.open(self.personal_path)
260        self.assertTrue('Updated' in self.browser.contents)
261        self.browser.getLink("Edit").click()
262        self.assertEqual(self.browser.headers['Status'], '200 Ok')
263        self.assertEqual(self.browser.url, self.edit_personal_path)
264        self.browser.getControl("Save").click()
265        self.assertMatches('...Required input is missing...',
266                           self.browser.contents)
267        self.browser.getControl(name="form.perm_address").value = 'My address!'
268        self.browser.getControl("Save").click()
269        self.assertMatches('...Required input is missing...',
270                           self.browser.contents)
271        # Ok, let's give up and fill the rest.
272        self.browser.getControl(name="form.next_kin_name").value = 'My Mutti'
273        self.browser.getControl(name="form.next_kin_relation").value = 'mother'
274        self.browser.getControl(name="form.next_kin_address").value = 'sweet home'
[9567]275        self.browser.getControl(name="form.next_kin_phone.country").value = ['+234']
276        self.browser.getControl(name="form.next_kin_phone.ext").value = '45678'
[9564]277        self.browser.getControl("Save").click()
278        self.assertMatches('...Form has been saved...',
279                           self.browser.contents)
280
[9239]281    def test_manage_upload_file(self):
282        # Managers can upload a file via the StudentClearanceManageFormPage
283        # The image is stored even if form has errors
284        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
285        self.browser.open(self.manage_clearance_path)
286        # Managers can add and delete a file
287        self.browser.open(self.manage_clearance_path)
288        image = open(SAMPLE_IMAGE, 'rb')
289        ctrl = self.browser.getControl(name='birthcertificateupload')
290        file_ctrl = ctrl.mech_control
291        file_ctrl.add_file(image, filename='my_acceptance_letter.jpg')
292        self.browser.getControl(
293            name='upload_acceptanceletterupload').click()
294        # Uups, we used the wrong 'Browse' field
295        self.assertFalse(
296            '<a target="image" href="acc_let">'
297            in self.browser.contents)
298        ctrl = self.browser.getControl(name='acceptanceletterupload')
299        file_ctrl = ctrl.mech_control
300        image.seek(0)
301        file_ctrl.add_file(image, filename='my_acceptance_letter.jpg')
302        self.browser.getControl(
303            name='upload_acceptanceletterupload').click()
304        self.assertTrue(
[11090]305            'http://localhost/app/students/K1000000/acc_let'
[9239]306            in self.browser.contents)
307        self.browser.getControl(
308            name='delete_acceptanceletterupload').click()
309        self.assertTrue(
310            'acc_let deleted'
[9562]311            in self.browser.contents)
312
313    def test_student_expired_personal_data(self):
314        # Login
[9582]315        IWorkflowState(self.student).setState('school fee paid')
[9562]316        delta = timedelta(days=180)
317        self.student.personal_updated = datetime.utcnow() - delta
318        self.browser.open(self.login_path)
319        self.browser.getControl(name="form.login").value = self.student_id
320        self.browser.getControl(name="form.password").value = 'spwd'
321        self.browser.getControl("Login").click()
322        self.assertEqual(self.browser.url, self.student_path)
323        self.assertTrue(
324            'You logged in' in self.browser.contents)
325        # Students don't see personal_updated field in edit form
326        self.browser.open(self.edit_personal_path)
327        self.assertFalse('Updated' in self.browser.contents)
328        self.browser.open(self.personal_path)
329        self.assertTrue('Updated' in self.browser.contents)
330        self.browser.getLink("Logout").click()
331        delta = timedelta(days=181)
332        self.student.personal_updated = datetime.utcnow() - delta
333        self.browser.open(self.login_path)
334        self.browser.getControl(name="form.login").value = self.student_id
335        self.browser.getControl(name="form.password").value = 'spwd'
336        self.browser.getControl("Login").click()
337        self.assertEqual(self.browser.url, self.edit_personal_path)
338        self.assertTrue(
[12503]339            'Your personal data record is outdated.' in self.browser.contents)
340
341    def test_lga_nationality(self):
342        self.student.nationality = u'DE'
343        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
344        self.browser.open(self.manage_clearance_path)
345        self.browser.getControl(name="form.lga").value = ['abia_aba_north']
346        self.browser.getControl("Save").click()
347        self.assertTrue(
348            'Nationalty and LGA are contradictory.' in self.browser.contents)
349        self.browser.getControl(name="form.nationality").value = ['NG']
350        self.browser.getControl("Save").click()
351        self.assertTrue(
352            'Form has been saved' in self.browser.contents)
[13620]353
354    def test_financial_clearance(self):
[15351]355        self.app['users'].addUser('mrbursary', SECRET)
[13620]356        self.app['users']['mrbursary'].email = 'mrbursary@foo.ng'
357        self.app['users']['mrbursary'].title = u'Carlo Pitter'
358        # Clearance officers needs to get
359        # the StudentsOfficer site role
360        prmglobal = IPrincipalRoleManager(self.app)
361        prmglobal.assignRoleToPrincipal('waeup.StudentsOfficer', 'mrbursary')
362        # Assign BursaryOfficer role
363        prmglobal.assignRoleToPrincipal('waeup.BursaryOfficer', 'mrbursary')
[13856]364        # and FinancialClearanceOfficer role
365        prmglobal.assignRoleToPrincipal(
366            'waeup.FinancialClearanceOfficer', 'mrbursary')
[13620]367        # Login
368        self.browser.open(self.login_path)
369        self.browser.getControl(name="form.login").value = 'mrbursary'
[15351]370        self.browser.getControl(name="form.password").value = SECRET
[13620]371        self.browser.getControl("Login").click()
372        # BO can see his roles
373        self.browser.getLink("My Roles").click()
374        self.assertMatches(
375            '...<div>Bursary Officer</div>...',
376            self.browser.contents)
377        # BO can view student record
378        self.browser.open(self.student_path)
379        # BO can see clearance button ...
380        self.assertTrue(
381            'Clear student financially' in self.browser.contents)
382        # ... but not withdraw button
383        self.assertFalse(
384            'Withdraw financial clearance' in self.browser.contents)
385        # BO can clear student
386        self.browser.getLink("Clear student financially").click()
387        self.assertTrue(
388            'Student has been financially cleared' in self.browser.contents)
389        # Name of BO and date have been stored
390        self.assertEqual(self.student.financially_cleared_by, 'Carlo Pitter')
391        self.assertMatches(
392            '<YYYY-MM-DD hh:mm:ss>',
393            self.student.financial_clearance_date.strftime(
394                "%Y-%m-%d %H:%M:%S"))
395        # BO can't see clearance button ...
396        self.assertFalse(
397            'Clear student financially' in self.browser.contents)
398        # ... but withdraw button and can withdraw clearance
399        self.browser.getLink("Withdraw financial clearance").click()
400        self.assertTrue(
401            'Financial clearance withdrawn' in self.browser.contents)
402        # Name of BO and date have been deleted
403        self.assertEqual(self.student.financially_cleared_by, None)
404        self.assertEqual(self.student.financial_clearance_date, None)
405        # Clearance is logged
406        logfile = os.path.join(
407            self.app['datacenter'].storage, 'logs', 'students.log')
408        logcontent = open(logfile).read()
409        self.assertTrue(
410            'mrbursary - kofacustom.nigeria.students.browser.ClearStudentFinancially'
411            ' - K1000000 - financially cleared' in logcontent)
412        self.assertTrue(
413            'mrbursary - kofacustom.nigeria.students.browser.WithdrawFinancialClearance'
414            ' - K1000000 - financial clearance withdrawn' in logcontent)
415        # Clearance is also stored in the history
416        self.browser.open(self.history_path)
417        self.assertMatches(
418            '...2016-01-16 15:50:48 WAT - Financially cleared by Carlo Pitter...',
419            self.browser.contents)
420        self.assertMatches(
421            '...2016-01-16 15:50:48 WAT - Financial clearance withdrawn by Carlo Pitter...',
422            self.browser.contents)
[13623]423
[13856]424    def test_fiancial_clearance_pdf_slip(self):
[13623]425        payment1 = createObject(u'waeup.StudentOnlinePayment')
426        timestamp = ("%d" % int(time()*10000))[1:]
[13634]427        payment1.p_id = "LSCNEW-2-4153206270" # the longest possible p_id
[13623]428        payment1.p_category = 'schoolfee'
429        payment1.p_item = u'My School Fee'
430        payment1.p_session = 2015
431        payment1.p_level = 100
432        payment1.p_current = True
433        payment1.amount_auth = 23456.9
434        payment1.approve()
435        payment2 = createObject(u'waeup.StudentOnlinePayment')
436        timestamp = ("%d" % int(time()*10000))[1:]
437        payment2.p_id = "p%s" % timestamp
438        payment2.p_category = 'clearance'
439        payment2.p_item = u'My Clearance Fee'
440        payment2.p_session = 2015
441        payment2.p_level = 100
442        payment2.p_current = True
443        payment2.amount_auth = 5678.6
444        payment2.approve()
445        self.student['payments'][payment1.p_id] = payment1
446        self.student['payments'][payment2.p_id] = payment2
447        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
448        self.browser.open(self.student_path + '/clear_financially')
[13781]449        self.browser.getLink("Download fee payment history").click()
[13623]450        self.assertEqual(self.browser.headers['Status'], '200 Ok')
451        self.assertEqual(self.browser.headers['Content-Type'],
452                         'application/pdf')
[13781]453        path = os.path.join(samples_dir(), 'fee_payment_history.pdf')
[13623]454        open(path, 'wb').write(self.browser.contents)
[13781]455        print "Sample PDF fee_payment_history.pdf written to %s" % path
[14274]456        return
457
[17866]458    def test_final_clearance(self):
459        self.app['users'].addUser('mrbursary', SECRET)
460        self.app['users']['mrbursary'].email = 'mrbursary@foo.ng'
461        self.app['users']['mrbursary'].title = u'Carl Pitter'
462        # Clearance officers needs to get
463        # the StudentsOfficer site role
464        prmglobal = IPrincipalRoleManager(self.app)
465        prmglobal.assignRoleToPrincipal('waeup.StudentsOfficer', 'mrbursary')
466        # Assign BursaryOfficer role
467        prmglobal.assignRoleToPrincipal('waeup.BursaryOfficer', 'mrbursary')
468        # and FinalClearanceOfficer role
469        prmglobal.assignRoleToPrincipal(
470            'waeup.FinalClearanceOfficer', 'mrbursary')
471        # Login
472        self.browser.open(self.login_path)
473        self.browser.getControl(name="form.login").value = 'mrbursary'
474        self.browser.getControl(name="form.password").value = SECRET
475        self.browser.getControl("Login").click()
476        # BO can see his roles
477        self.browser.getLink("My Roles").click()
478        self.assertMatches(
479            '...<div>Bursary Officer</div>...',
480            self.browser.contents)
481        # BO can view student record
482        self.browser.open(self.student_path)
483        # BO can see clearance button ...
484        self.assertTrue(
485            'Clear student finally' in self.browser.contents)
486        # ... but not withdraw button
487        self.assertFalse(
488            'Withdraw final clearance' in self.browser.contents)
489        # BO can clear student
490        self.browser.getLink("Clear student finally").click()
491        self.assertTrue(
492            'Student has been finally cleared' in self.browser.contents)
493        # Name of BO and date have been stored
494        self.assertEqual(self.student.finally_cleared_by, 'Carl Pitter')
495        self.assertMatches(
496            '<YYYY-MM-DD hh:mm:ss>',
497            self.student.final_clearance_date.strftime(
498                "%Y-%m-%d %H:%M:%S"))
499        # BO can't see clearance button ...
500        self.assertFalse(
501            'Clear student finally' in self.browser.contents)
502        # ... but withdraw button and can withdraw clearance
503        self.browser.getLink("Withdraw final clearance").click()
504        self.assertTrue(
505            'Final clearance withdrawn' in self.browser.contents)
506        # Name of BO and date have been deleted
507        self.assertEqual(self.student.finally_cleared_by, None)
508        self.assertEqual(self.student.final_clearance_date, None)
509        # Clearance is logged
510        logfile = os.path.join(
511            self.app['datacenter'].storage, 'logs', 'students.log')
512        logcontent = open(logfile).read()
513        self.assertTrue(
514            'mrbursary - kofacustom.nigeria.students.browser.ClearStudentFinally'
515            ' - K1000000 - finally cleared' in logcontent)
516        self.assertTrue(
517            'mrbursary - kofacustom.nigeria.students.browser.WithdrawFinalClearance'
518            ' - K1000000 - final clearance withdrawn' in logcontent)
519        # Clearance is also stored in the history
520        self.browser.open(self.history_path)
521        self.assertMatches(
522            '...2016-01-16 15:50:48 WAT - Finally cleared by Carl Pitter...',
523            self.browser.contents)
524        self.assertMatches(
525            '...2016-01-16 15:50:48 WAT - Final clearance withdrawn by Carl Pitter...',
526            self.browser.contents)
527
[14274]528    def test_provisionally_cleared(self):
529        # Students can edit clearance data
530        IWorkflowState(self.student).setState('school fee paid')
531        self.browser.open(self.login_path)
532        self.browser.getControl(name="form.login").value = self.student_id
533        self.browser.getControl(name="form.password").value = 'spwd'
534        self.browser.getControl("Login").click()
535        # Student can't access the clearance form
536        self.browser.open(self.student_path)
537        self.browser.getLink("Clearance Data").click()
538        # Student can't open clearance edit form before starting clearance
539        self.browser.open(self.student_path + '/cedit')
540        self.assertMatches('...The requested form is locked...',
541                           self.browser.contents)
542        self.assertFalse(
543            '<h1 class="kofa-content-label">Edit clearance data</h1>'
544            in self.browser.contents)
545        # If provisionally_cleared is set they can
546        self.student.provisionally_cleared = True
547        self.browser.getLink("Clearance Data").click()
548        self.browser.getLink("Edit").click()
549        self.assertTrue(
550            '<h1 class="kofa-content-label">Edit clearance data</h1>'
551            in self.browser.contents)
[17611]552
553    def test_student_redirect_camefrom(self):
554        payment1 = createObject(u'waeup.StudentOnlinePayment')
555        payment1.p_id = "p4153206270"
556        payment1.p_category = 'schoolfee'
557        payment1.p_item = u'My School Fee'
558        payment1.p_session = 2015
559        payment1.p_level = 100
560        payment1.p_current = True
561        payment1.amount_auth = 23456.9
562        payment1.approve()
563        self.student['payments'][payment1.p_id] = payment1
564        self.browser.open(self.login_path)
565        self.browser.getControl(name="form.login").value = self.student_id
566        self.browser.getControl(name="form.password").value = 'spwd'
567        self.browser.getControl("Login").click()
568        self.assertMatches(
569            '...You logged in...', self.browser.contents)
570        camefrom = '/students/K1000000/studycourse'
571        self.browser.open(self.login_path + '?camefrom=%s' % camefrom)
572        # nothing happens
573        self.assertEqual(self.browser.url, self.login_path + '?camefrom=%s' % camefrom)
574        camefrom = '/students/K1000000/payments/%s/request_webservice' % payment1.p_id
575        # Kofa redirects to request_webservice and then returns to payment ticket index view
576        self.browser.open(self.login_path + '?camefrom=%s' % camefrom)
577        self.assertEqual(
578            self.browser.url,
579            'http://localhost/app/students/K1000000/payments/p4153206270/@@index')
Note: See TracBrowser for help on using the repository browser.