[7419] | 1 | ## $Id: test_browser.py 17885 2024-08-11 19:29:13Z 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 | ## |
---|
[7604] | 18 | import os |
---|
| 19 | import shutil |
---|
| 20 | import tempfile |
---|
[13251] | 21 | import pytz |
---|
[17845] | 22 | from time import time |
---|
[13251] | 23 | from datetime import datetime, timedelta, date |
---|
[8720] | 24 | from StringIO import StringIO |
---|
[9210] | 25 | from hurry.workflow.interfaces import IWorkflowState, IWorkflowInfo |
---|
| 26 | from zope.securitypolicy.interfaces import IPrincipalRoleManager |
---|
[13251] | 27 | from zope.security.interfaces import Unauthorized |
---|
[7604] | 28 | from zope.component.hooks import setSite, clearSite |
---|
[8326] | 29 | from zope.component import getUtility, createObject |
---|
| 30 | from zope.interface import verify |
---|
[9210] | 31 | from zope.event import notify |
---|
| 32 | from waeup.kofa.authentication import LocalRoleSetEvent |
---|
[7822] | 33 | from waeup.kofa.app import University |
---|
[14834] | 34 | from waeup.kofa.university.faculty import Faculty |
---|
| 35 | from waeup.kofa.university.department import Department |
---|
[7822] | 36 | from waeup.kofa.students.tests.test_browser import StudentsFullSetup |
---|
[9435] | 37 | from waeup.kofa.students.accommodation import BedTicket |
---|
[13251] | 38 | from waeup.kofa.hostels.hostel import Hostel, Bed, NOT_OCCUPIED |
---|
[7822] | 39 | from waeup.kofa.testing import FunctionalTestCase |
---|
[12121] | 40 | from waeup.kofa.browser.tests.test_pdf import samples_dir |
---|
[8720] | 41 | from waeup.kofa.interfaces import ( |
---|
| 42 | IExtFileStore, IFileStoreNameChooser) |
---|
[8320] | 43 | from waeup.kofa.students.interfaces import IStudentsUtils |
---|
[15371] | 44 | from waeup.kofa.tests.test_authentication import SECRET |
---|
[8020] | 45 | from waeup.uniben.testing import FunctionalLayer |
---|
[6902] | 46 | |
---|
[11611] | 47 | SAMPLE_FPM = os.path.join(os.path.dirname(__file__), 'sample.fpm') |
---|
[16456] | 48 | SAMPLE_PASSPORT = os.path.join(os.path.dirname(__file__), 'test_image.jpg') |
---|
[8320] | 49 | |
---|
[15371] | 50 | class OfficerUITests(StudentsFullSetup): |
---|
| 51 | # Tests for Student class views and pages |
---|
| 52 | |
---|
| 53 | layer = FunctionalLayer |
---|
| 54 | |
---|
| 55 | def test_jhl_idcard_officer(self): |
---|
| 56 | # Create library officer |
---|
| 57 | self.app['users'].addUser('mrlibrary', SECRET) |
---|
| 58 | self.app['users']['mrlibrary'].email = 'library@foo.ng' |
---|
| 59 | self.app['users']['mrlibrary'].title = 'Carlo Pitter' |
---|
| 60 | prmglobal = IPrincipalRoleManager(self.app) |
---|
| 61 | prmglobal.assignRoleToPrincipal( |
---|
| 62 | 'waeup.LibraryClearanceOfficer', 'mrlibrary') |
---|
| 63 | prmglobal.assignRoleToPrincipal( |
---|
| 64 | 'waeup.StudentsOfficer', 'mrlibrary') |
---|
| 65 | self.browser.open(self.login_path) |
---|
| 66 | self.browser.getControl(name="form.login").value = 'mrlibrary' |
---|
| 67 | self.browser.getControl(name="form.password").value = SECRET |
---|
| 68 | self.browser.getControl("Login").click() |
---|
| 69 | self.assertMatches('...You logged in...', self.browser.contents) |
---|
| 70 | self.browser.open(self.student_path) |
---|
| 71 | self.assertFalse('JHL' in self.browser.contents) |
---|
| 72 | self.browser.getLink("Switch library access").click() |
---|
| 73 | self.assertTrue('Library access enabled' in self.browser.contents) |
---|
| 74 | self.assertTrue('JHL' in self.browser.contents) |
---|
| 75 | self.browser.getLink("Download JHL Id Card").click() |
---|
| 76 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 77 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
| 78 | path = os.path.join(samples_dir(), 'jhl_idcard_officer.pdf') |
---|
| 79 | open(path, 'wb').write(self.browser.contents) |
---|
| 80 | print "Sample PDF jhl_idcard_officer.pdf written to %s" % path |
---|
| 81 | |
---|
[6902] | 82 | class StudentUITests(StudentsFullSetup): |
---|
[7604] | 83 | """Tests for customized student class views and pages |
---|
| 84 | """ |
---|
[6902] | 85 | |
---|
| 86 | layer = FunctionalLayer |
---|
| 87 | |
---|
[9435] | 88 | def setUp(self): |
---|
| 89 | super(StudentUITests, self).setUp() |
---|
| 90 | |
---|
[9251] | 91 | def test_next_session_allowed(self): |
---|
| 92 | # Let's see if next_session_allowed works as expected |
---|
| 93 | # A, ug_ft, 100 |
---|
| 94 | IWorkflowState(self.student).setState('returning') |
---|
| 95 | self.assertTrue(self.student['studycourse'].next_session_allowed) |
---|
| 96 | # Uniben special PG programmes have the same workflow |
---|
| 97 | # as UG students |
---|
| 98 | self.certificate.study_mode = 'special_pg_pt' |
---|
| 99 | self.assertTrue(self.student['studycourse'].next_session_allowed) |
---|
| 100 | IWorkflowState(self.student).setState('school fee paid') |
---|
| 101 | self.assertFalse(self.student['studycourse'].next_session_allowed) |
---|
| 102 | # Now we convert the certificate into a 'regular |
---|
| 103 | # postgraduate certificate ... |
---|
| 104 | self.certificate.study_mode = 'pg_ft' |
---|
| 105 | # ... and voila next session registration is allowed |
---|
| 106 | self.assertTrue(self.student['studycourse'].next_session_allowed) |
---|
| 107 | |
---|
| 108 | def test_manage_access(self): |
---|
| 109 | self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') |
---|
| 110 | # The student created in the base package is a ug student |
---|
| 111 | self.browser.open(self.manage_clearance_path) |
---|
| 112 | self.assertMatches('...First Sitting Record...', |
---|
| 113 | self.browser.contents) |
---|
| 114 | # There is no pg field in the clearance form |
---|
| 115 | self.assertFalse('Second Higher Education Record' |
---|
| 116 | in self.browser.contents) |
---|
| 117 | # Now we change the study mode ... |
---|
| 118 | self.certificate.study_mode = 'pg_ft' |
---|
| 119 | self.browser.open(self.clearance_path) |
---|
[10902] | 120 | # ... and additional pg clearance fields appears |
---|
[9251] | 121 | self.assertMatches('...Second Higher Education Record...', |
---|
| 122 | self.browser.contents) |
---|
| 123 | # But also fields from the ug form are displayed |
---|
| 124 | self.assertMatches('...First Sitting Record...', |
---|
| 125 | self.browser.contents) |
---|
| 126 | # The same holds for Uniben's special pg students |
---|
[10740] | 127 | self.certificate.study_mode = 'special_pg_pt' |
---|
[9251] | 128 | self.browser.open(self.clearance_path) |
---|
| 129 | self.assertMatches('...Second Higher Education Record...', |
---|
| 130 | self.browser.contents) |
---|
| 131 | self.assertMatches('...First Sitting Record...', |
---|
| 132 | self.browser.contents) |
---|
[12846] | 133 | # We want to see the signature fields. |
---|
| 134 | IWorkflowState(self.student).setState('returning') |
---|
[9459] | 135 | self.browser.open(self.student_path + '/clearance_slip.pdf') |
---|
| 136 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 137 | self.assertEqual(self.browser.headers['Content-Type'], |
---|
| 138 | 'application/pdf') |
---|
[12846] | 139 | path = os.path.join(samples_dir(), 'clearance_slip.pdf') |
---|
| 140 | open(path, 'wb').write(self.browser.contents) |
---|
| 141 | print "Sample PDF clearance_slip.pdf written to %s" % path |
---|
[9251] | 142 | |
---|
[9380] | 143 | def test_student_access(self): |
---|
| 144 | # Students can edit clearance data |
---|
| 145 | IWorkflowState(self.student).setState('clearance started') |
---|
| 146 | self.student.nationality = u'NG' |
---|
[16458] | 147 | self.student['studycourse'].entry_mode = 'ug_ft' |
---|
[9380] | 148 | file_store = getUtility(IExtFileStore) |
---|
| 149 | self.browser.open(self.login_path) |
---|
| 150 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 151 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 152 | self.browser.getControl("Login").click() |
---|
| 153 | self.browser.open(self.edit_clearance_path) |
---|
[11553] | 154 | # UG students can't edit date_of_birth, nationality and lga |
---|
| 155 | self.assertFalse('form.date_of_birth' in self.browser.contents) |
---|
| 156 | self.assertFalse('form.nationality' in self.browser.contents) |
---|
| 157 | self.assertFalse('form.lga' in self.browser.contents) |
---|
[9380] | 158 | # Clearance can only be requested if all required documents |
---|
| 159 | # have been uploaded. |
---|
| 160 | self.browser.getControl("Save and request clearance").click() |
---|
[16456] | 161 | |
---|
| 162 | self.assertTrue('No red background passport picture uploaded' |
---|
| 163 | in self.browser.contents) |
---|
| 164 | passport = 'My passport picture' |
---|
| 165 | file_id = IFileStoreNameChooser(self.student).chooseName( |
---|
| 166 | attr="passport.jpg") |
---|
| 167 | image = open(SAMPLE_PASSPORT, 'rb') |
---|
| 168 | file_store.createFile(file_id, image) |
---|
| 169 | self.browser.open(self.edit_clearance_path) |
---|
| 170 | self.browser.getControl("Save and request clearance").click() |
---|
| 171 | |
---|
[9380] | 172 | self.assertTrue('No birth certificate uploaded' |
---|
| 173 | in self.browser.contents) |
---|
| 174 | birth_certificate = 'My birth certificate' |
---|
| 175 | file_id = IFileStoreNameChooser(self.student).chooseName( |
---|
| 176 | attr="birth_certificate.jpg") |
---|
| 177 | file_store.createFile(file_id, StringIO(birth_certificate)) |
---|
| 178 | self.browser.open(self.edit_clearance_path) |
---|
| 179 | self.browser.getControl("Save and request clearance").click() |
---|
| 180 | |
---|
| 181 | self.assertTrue('No guarantor/referee letter uploaded' |
---|
| 182 | in self.browser.contents) |
---|
| 183 | ref_let = 'My ref let' |
---|
| 184 | file_id = IFileStoreNameChooser(self.student).chooseName( |
---|
| 185 | attr="ref_let.jpg") |
---|
| 186 | file_store.createFile(file_id, StringIO(ref_let)) |
---|
| 187 | self.browser.open(self.edit_clearance_path) |
---|
| 188 | self.browser.getControl("Save and request clearance").click() |
---|
| 189 | |
---|
| 190 | self.assertTrue('No acceptance letter uploaded' |
---|
| 191 | in self.browser.contents) |
---|
| 192 | acc_let = 'My acc let' |
---|
| 193 | file_id = IFileStoreNameChooser(self.student).chooseName( |
---|
| 194 | attr="acc_let.jpg") |
---|
| 195 | file_store.createFile(file_id, StringIO(acc_let)) |
---|
| 196 | self.browser.open(self.edit_clearance_path) |
---|
| 197 | self.browser.getControl("Save and request clearance").click() |
---|
| 198 | |
---|
| 199 | self.assertTrue('No first sitting result uploaded' |
---|
| 200 | in self.browser.contents) |
---|
| 201 | fst_sit_scan = 'My first sitting result' |
---|
| 202 | file_id = IFileStoreNameChooser(self.student).chooseName( |
---|
| 203 | attr="fst_sit_scan.jpg") |
---|
| 204 | file_store.createFile(file_id, StringIO(fst_sit_scan)) |
---|
| 205 | self.browser.open(self.edit_clearance_path) |
---|
| 206 | self.browser.getControl("Save and request clearance").click() |
---|
| 207 | |
---|
[9848] | 208 | self.assertTrue('No affidavit of non-membership of secret cults uploaded' |
---|
[9380] | 209 | in self.browser.contents) |
---|
| 210 | secr_cults = 'My non-membership scan' |
---|
| 211 | file_id = IFileStoreNameChooser(self.student).chooseName( |
---|
| 212 | attr="secr_cults.jpg") |
---|
| 213 | file_store.createFile(file_id, StringIO(secr_cults)) |
---|
[16447] | 214 | self.browser.open(self.edit_clearance_path) |
---|
| 215 | self.browser.getControl("Save and request clearance").click() |
---|
| 216 | |
---|
| 217 | self.assertTrue('No O level results scratch card uploaded' |
---|
| 218 | in self.browser.contents) |
---|
| 219 | olevel_sc = 'My O level results scratch card' |
---|
| 220 | file_id = IFileStoreNameChooser(self.student).chooseName( |
---|
| 221 | attr="olevel_sc.jpg") |
---|
| 222 | file_store.createFile(file_id, StringIO(olevel_sc)) |
---|
| 223 | |
---|
[12122] | 224 | # Clearance invitation letter is not yet available |
---|
| 225 | self.browser.open(self.clearance_path) |
---|
| 226 | self.assertFalse('invitation slip' in self.browser.contents) |
---|
| 227 | self.browser.open(self.student_path + '/clearance_invitation_slip.pdf') |
---|
| 228 | self.assertTrue('Forbidden' in self.browser.contents) |
---|
[9380] | 229 | self.browser.open(self.edit_clearance_path) |
---|
| 230 | self.browser.getControl("Save and request clearance").click() |
---|
| 231 | self.assertTrue('Clearance has been requested' |
---|
| 232 | in self.browser.contents) |
---|
[17542] | 233 | # Now student can export physical_clearance_slip |
---|
[12121] | 234 | self.app['configuration'].name = u'University of Benin' |
---|
| 235 | self.student.physical_clearance_date = u'January 5th, 2015' |
---|
| 236 | self.browser.getLink("Clearance Data").click() |
---|
| 237 | self.browser.getLink("Download clearance invitation slip").click() |
---|
| 238 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 239 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
| 240 | path = os.path.join(samples_dir(), 'clearance_invitation_slip.pdf') |
---|
| 241 | open(path, 'wb').write(self.browser.contents) |
---|
| 242 | print "Sample PDF clearance_invitation_slip.pdf written to %s" % path |
---|
[17542] | 243 | |
---|
| 244 | def test_medical_examination_slip(self): |
---|
| 245 | # Student can export medical_examination_slip |
---|
| 246 | self.app['configuration']['2004'].medical_clearance_fee = 1000.0 |
---|
| 247 | self.app['configuration'].name = u'University of Benin' |
---|
| 248 | IWorkflowState(self.student).setState('cleared') |
---|
| 249 | self.student.perm_address = u'My Address in Nigeria' |
---|
| 250 | self.student.physical_clearance_date = u'January 5th, 2015' |
---|
| 251 | self.browser.open(self.login_path) |
---|
| 252 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 253 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 254 | self.browser.getControl("Login").click() |
---|
| 255 | self.browser.open(self.clearance_path) |
---|
| 256 | self.browser.getLink("Download medical examination slip").click() |
---|
| 257 | self.assertTrue('Please pay medical clearance fee first' in |
---|
| 258 | self.browser.contents) |
---|
| 259 | self.browser.open(self.payments_path) |
---|
| 260 | self.browser.getLink("Add current session payment ticket").click() |
---|
| 261 | self.browser.getControl(name="form.p_category").value = ['medical_clearance'] |
---|
| 262 | self.browser.getControl("Create ticket").click() |
---|
| 263 | p_ticket = self.student['payments'].values()[0] |
---|
| 264 | p_ticket.approveStudentPayment() |
---|
| 265 | self.browser.open(self.clearance_path) |
---|
| 266 | self.browser.getLink("Download medical examination slip").click() |
---|
| 267 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 268 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
| 269 | path = os.path.join(samples_dir(), 'medical_examination_slip.pdf') |
---|
| 270 | open(path, 'wb').write(self.browser.contents) |
---|
| 271 | print "Sample PDF medical_examination_slip.pdf written to %s" % path |
---|
| 272 | |
---|
[13085] | 273 | # Students can open the personal edit page and see the parent_email field. |
---|
| 274 | self.browser.open(self.student_path + '/edit_personal') |
---|
| 275 | self.assertTrue('parent_email' in self.browser.contents) |
---|
[9380] | 276 | |
---|
[13723] | 277 | def test_examination_schedule_slip(self): |
---|
| 278 | self.student.flash_notice = u'My Examination Date' |
---|
| 279 | self.browser.open(self.login_path) |
---|
| 280 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 281 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 282 | self.browser.getControl("Login").click() |
---|
[16330] | 283 | self.browser.open(self.student_path) |
---|
[13723] | 284 | self.browser.getLink("Download examination schedule slip").click() |
---|
| 285 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 286 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
| 287 | path = os.path.join(samples_dir(), 'examination_schedule_slip.pdf') |
---|
| 288 | open(path, 'wb').write(self.browser.contents) |
---|
| 289 | print "Sample PDF examination_schedule_slip.pdf written to %s" % path |
---|
| 290 | # If flash_notive does not contain exam' the button does not show up. |
---|
| 291 | self.student.flash_notice = u'anything' |
---|
| 292 | self.browser.open(self.student_path) |
---|
| 293 | self.assertFalse('examination schedule slip' in self.browser.contents) |
---|
| 294 | |
---|
[15352] | 295 | def test_jhl_idcard(self): |
---|
[15403] | 296 | IWorkflowState(self.student).setState('returning') |
---|
[15352] | 297 | self.browser.open(self.login_path) |
---|
| 298 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 299 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 300 | self.browser.getControl("Login").click() |
---|
[15371] | 301 | self.assertFalse('JHL' in self.browser.contents) |
---|
| 302 | self.student.library = True |
---|
| 303 | self.browser.open(self.student_path) |
---|
| 304 | self.assertTrue('JHL' in self.browser.contents) |
---|
[15352] | 305 | self.browser.getLink("Download JHL Id Card").click() |
---|
| 306 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 307 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
[15371] | 308 | path = os.path.join(samples_dir(), 'jhl_idcard_student.pdf') |
---|
[15352] | 309 | open(path, 'wb').write(self.browser.contents) |
---|
[15371] | 310 | print "Sample PDF jhl_idcard_student.pdf written to %s" % path |
---|
[15403] | 311 | self.assertTrue(self.student.library) |
---|
| 312 | IWorkflowInfo(self.student).fireTransition('pay_school_fee') |
---|
| 313 | self.assertFalse(self.student.library) |
---|
[15352] | 314 | |
---|
[14834] | 315 | def test_jupeb_result_slip(self): |
---|
| 316 | self.student.flash_notice = u'My JUPEB results' |
---|
| 317 | self.browser.open(self.login_path) |
---|
| 318 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 319 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 320 | self.browser.getControl("Login").click() |
---|
| 321 | self.assertFalse('JUPEB result slip' in self.browser.contents) |
---|
| 322 | # Create JUPEB faculty |
---|
| 323 | cert = createObject('waeup.Certificate') |
---|
| 324 | cert.code = u'xyz' |
---|
[16360] | 325 | cert.study_mode = 'found' |
---|
[14902] | 326 | self.app['faculties']['JUPEB123'] = Faculty(code=u'JUPEB123') |
---|
| 327 | self.app['faculties']['JUPEB123']['dep1'] = Department(code=u'dep1') |
---|
| 328 | self.app['faculties']['JUPEB123']['dep1'].certificates.addCertificate(cert) |
---|
[14834] | 329 | self.student['studycourse'].certificate = cert |
---|
| 330 | self.browser.open(self.student_path) |
---|
| 331 | self.browser.getLink("Download JUPEB result slip").click() |
---|
| 332 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 333 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
| 334 | path = os.path.join(samples_dir(), 'jupeb_result_slip.pdf') |
---|
| 335 | open(path, 'wb').write(self.browser.contents) |
---|
| 336 | print "Sample PDF jupeb_result_slip.pdf written to %s" % path |
---|
| 337 | self.student.flash_notice = u'' |
---|
| 338 | self.browser.open(self.student_path) |
---|
| 339 | self.assertFalse('JUPEB result slip' in self.browser.contents) |
---|
| 340 | |
---|
[6902] | 341 | def test_manage_payments(self): |
---|
[7021] | 342 | # Add missing configuration data |
---|
[7928] | 343 | self.app['configuration']['2004'].gown_fee = 150.0 |
---|
| 344 | self.app['configuration']['2004'].transfer_fee = 90.0 |
---|
[8294] | 345 | #self.app['configuration']['2004'].clearance_fee = 120.0 |
---|
| 346 | self.app['configuration']['2004'].booking_fee = 150.0 |
---|
[7928] | 347 | self.app['configuration']['2004'].maint_fee = 180.0 |
---|
[6925] | 348 | |
---|
[6926] | 349 | # Managers can add online payment tickets |
---|
| 350 | self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') |
---|
[7995] | 351 | self.browser.open(self.payments_path) |
---|
[9520] | 352 | self.browser.getLink("Add current session payment ticket").click() |
---|
[15106] | 353 | self.browser.getControl(name="form.p_category").value = ['schoolfee'] |
---|
[6926] | 354 | self.browser.getControl("Create ticket").click() |
---|
[6925] | 355 | self.assertMatches('...Amount could not be determined...', |
---|
[6902] | 356 | self.browser.contents) |
---|
[7886] | 357 | IWorkflowState(self.student).setState('cleared') |
---|
[9006] | 358 | self.student.nationality = u'NG' |
---|
[7995] | 359 | self.browser.open(self.payments_path + '/addop') |
---|
[9731] | 360 | self.browser.getControl(name="form.p_category").value = ['schoolfee'] |
---|
[6902] | 361 | self.browser.getControl("Create ticket").click() |
---|
| 362 | self.assertMatches('...ticket created...', |
---|
| 363 | self.browser.contents) |
---|
[7419] | 364 | self.assertMatches('...Amount Authorized...', |
---|
| 365 | self.browser.contents) |
---|
[15828] | 366 | # Managers can open payment slip because we did not proceed to |
---|
| 367 | # any payment gateway |
---|
| 368 | self.assertFalse('Download payment slip' in self.browser.contents) |
---|
[7891] | 369 | # Set ticket paid |
---|
| 370 | ticket = self.student['payments'].items()[0][1] |
---|
| 371 | ticket.p_state = 'paid' |
---|
[7995] | 372 | self.browser.open(self.payments_path + '/addop') |
---|
[9731] | 373 | self.browser.getControl(name="form.p_category").value = ['schoolfee'] |
---|
[7889] | 374 | self.browser.getControl("Create ticket").click() |
---|
[7419] | 375 | self.assertMatches('...This type of payment has already been made...', |
---|
[7146] | 376 | self.browser.contents) |
---|
| 377 | # Remove all payments so that we can add a school fee payment again |
---|
[7889] | 378 | keys = [i for i in self.student['payments'].keys()] |
---|
| 379 | for payment in keys: |
---|
[7146] | 380 | del self.student['payments'][payment] |
---|
[7995] | 381 | self.browser.open(self.payments_path + '/addop') |
---|
[9731] | 382 | self.browser.getControl(name="form.p_category").value = ['schoolfee'] |
---|
[7146] | 383 | self.browser.getControl("Create ticket").click() |
---|
[6925] | 384 | self.assertMatches('...ticket created...', |
---|
| 385 | self.browser.contents) |
---|
[9520] | 386 | schoolfee_ticket = self.student['payments'].values()[0] |
---|
[7995] | 387 | self.browser.open(self.payments_path + '/addop') |
---|
[6926] | 388 | self.browser.getControl(name="form.p_category").value = ['gown'] |
---|
| 389 | self.browser.getControl("Create ticket").click() |
---|
[8294] | 390 | self.assertMatches('...ticket created...', |
---|
| 391 | self.browser.contents) |
---|
[7995] | 392 | self.browser.open(self.payments_path + '/addop') |
---|
[14897] | 393 | self.browser.getControl(name="form.p_category").value = ['clearance'] |
---|
| 394 | self.browser.getControl("Create ticket").click() |
---|
| 395 | self.assertMatches('...ticket created...', |
---|
| 396 | self.browser.contents) |
---|
[16330] | 397 | self.assertTrue('<span>60000.0</span>' in self.browser.contents) |
---|
[7995] | 398 | self.browser.open(self.payments_path + '/addop') |
---|
[6926] | 399 | self.browser.getControl(name="form.p_category").value = ['schoolfee'] |
---|
| 400 | self.browser.getControl("Create ticket").click() |
---|
[8306] | 401 | self.assertMatches('...ticket created...', |
---|
| 402 | self.browser.contents) |
---|
| 403 | # In state returning we can add a new school fee ticket since |
---|
| 404 | # p_session and p_level is different |
---|
| 405 | IWorkflowState(self.student).setState('returning') |
---|
| 406 | self.browser.open(self.payments_path + '/addop') |
---|
| 407 | self.browser.getControl(name="form.p_category").value = ['schoolfee'] |
---|
| 408 | self.browser.getControl("Create ticket").click() |
---|
[9520] | 409 | # Uups, we forgot to add a session configuration for next session |
---|
[8959] | 410 | self.assertMatches('...Session configuration object is not...', |
---|
| 411 | self.browser.contents) |
---|
| 412 | configuration = createObject('waeup.SessionConfiguration') |
---|
| 413 | configuration.academic_session = 2005 |
---|
| 414 | self.app['configuration'].addSessionConfiguration(configuration) |
---|
| 415 | self.browser.open(self.payments_path + '/addop') |
---|
| 416 | self.browser.getControl(name="form.p_category").value = ['schoolfee'] |
---|
| 417 | self.browser.getControl("Create ticket").click() |
---|
[9570] | 418 | |
---|
| 419 | #self.assertMatches('...You have not yet paid your current/active session...', |
---|
| 420 | # self.browser.contents) |
---|
| 421 | ## Ok, let's pay the first schoolfee ticket. |
---|
| 422 | #schoolfee_ticket.approve() |
---|
| 423 | #self.browser.open(self.payments_path + '/addop') |
---|
| 424 | #self.browser.getControl(name="form.p_category").value = ['schoolfee'] |
---|
| 425 | #self.browser.getControl("Create ticket").click() |
---|
| 426 | |
---|
[8306] | 427 | self.assertMatches('...ticket created...', |
---|
| 428 | self.browser.contents) |
---|
[8320] | 429 | # In state admitted school fee can't be determined |
---|
[8306] | 430 | IWorkflowState(self.student).setState('admitted') |
---|
| 431 | self.browser.open(self.payments_path + '/addop') |
---|
| 432 | self.browser.getControl(name="form.p_category").value = ['schoolfee'] |
---|
| 433 | self.browser.getControl("Create ticket").click() |
---|
[6926] | 434 | self.assertMatches('...Amount could not be determined...', |
---|
| 435 | self.browser.contents) |
---|
| 436 | |
---|
[8306] | 437 | # If the session configuration doesn't exist an error message will |
---|
| 438 | # be shown. No other requirement is being checked. |
---|
[7021] | 439 | del self.app['configuration']['2004'] |
---|
[7995] | 440 | self.browser.open(self.payments_path) |
---|
[9520] | 441 | self.browser.getLink("Add current session payment ticket").click() |
---|
[7021] | 442 | self.browser.getControl("Create ticket").click() |
---|
| 443 | self.assertMatches('...Session configuration object is not...', |
---|
| 444 | self.browser.contents) |
---|
[8267] | 445 | |
---|
[9686] | 446 | def test_student_course_registration(self): |
---|
| 447 | # Uniben students see grade instead of score on all level pages |
---|
| 448 | # and on course ticket page. |
---|
| 449 | IWorkflowState(self.student).setState('school fee paid') |
---|
| 450 | self.browser.open(self.login_path) |
---|
| 451 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 452 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 453 | self.browser.getControl("Login").click() |
---|
| 454 | # Now students can add the current study level |
---|
| 455 | self.browser.getLink("Study Course").click() |
---|
| 456 | self.browser.getLink("Add course list").click() |
---|
| 457 | self.assertMatches('...Add current level 100 (Year 1)...', |
---|
| 458 | self.browser.contents) |
---|
| 459 | self.browser.getControl("Create course list now").click() |
---|
| 460 | # A level with one course ticket was created |
---|
| 461 | self.assertEqual(self.student['studycourse']['100'].number_of_tickets, 1) |
---|
[9688] | 462 | self.student['studycourse']['100']['COURSE1'].score = 55 |
---|
[9686] | 463 | self.browser.getLink("100").click() |
---|
[10284] | 464 | # GPA has been properly calculated |
---|
| 465 | self.assertEqual(self.student['studycourse']['100'].gpa_params[0], 3.0) |
---|
[9688] | 466 | # Score is not shown but grade |
---|
[9686] | 467 | self.assertTrue('<th>Grade</th>' in self.browser.contents) |
---|
| 468 | self.assertFalse('<th>Score</th>' in self.browser.contents) |
---|
| 469 | self.browser.getLink("Edit course list").click() |
---|
| 470 | self.assertTrue('<th>Grade</th>' in self.browser.contents) |
---|
| 471 | self.assertFalse('<th>Score</th>' in self.browser.contents) |
---|
| 472 | self.browser.getLink("COURSE1").click() |
---|
| 473 | self.assertFalse('Score' in self.browser.contents) |
---|
[9848] | 474 | # Students can open the special Uniben pdf course result slip |
---|
| 475 | self.browser.open(self.student_path + '/studycourse/100') |
---|
| 476 | self.browser.getLink("Download course result slip").click() |
---|
| 477 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 478 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
[9765] | 479 | # Even if course is mandatory, students can remove the course |
---|
| 480 | self.student['studycourse']['100']['COURSE1'].mandatory = True |
---|
| 481 | self.browser.open(self.student_path + '/studycourse/100') |
---|
| 482 | self.browser.getLink("Edit course list").click() |
---|
| 483 | ctrl = self.browser.getControl(name='val_id') |
---|
| 484 | ctrl.getControl(value='COURSE1').selected = True |
---|
| 485 | self.browser.getControl("Remove selected", index=0).click() |
---|
| 486 | self.assertTrue('Successfully removed' in self.browser.contents) |
---|
[12855] | 487 | # Students can open the customized pdf course registration slip |
---|
| 488 | # if they have registered their course list |
---|
| 489 | self.browser.open( |
---|
| 490 | self.student_path + '/studycourse/100/course_registration_slip.pdf') |
---|
| 491 | self.assertTrue('Forbidden' in self.browser.contents) |
---|
| 492 | IWorkflowState(self.student).setState('courses registered') |
---|
| 493 | self.browser.open(self.student_path + '/studycourse/100') |
---|
| 494 | self.browser.getLink("Download course registration slip").click() |
---|
| 495 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 496 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
[15401] | 497 | path = os.path.join(samples_dir(), 'course_registration_slip.pdf') |
---|
| 498 | open(path, 'wb').write(self.browser.contents) |
---|
| 499 | print "Sample PDF course_registration_slip.pdf written to %s" % path |
---|
| 500 | # Students can always download pdf course result slip |
---|
| 501 | self.browser.open( |
---|
| 502 | self.student_path + '/studycourse/100/course_result_slip.pdf') |
---|
| 503 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 504 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
| 505 | path = os.path.join(samples_dir(), 'course_result_slip.pdf') |
---|
| 506 | open(path, 'wb').write(self.browser.contents) |
---|
| 507 | print "Sample PDF course_result_slip.pdf written to %s" % path |
---|
[9686] | 508 | |
---|
[8320] | 509 | def test_get_returning_data(self): |
---|
| 510 | # Student is in level 100, session 2004 with verdict A |
---|
| 511 | utils = getUtility(IStudentsUtils) |
---|
| 512 | self.assertEqual(utils.getReturningData(self.student),(2005, 200)) |
---|
| 513 | self.student['studycourse'].current_verdict = 'C' |
---|
| 514 | self.assertEqual(utils.getReturningData(self.student),(2005, 110)) |
---|
| 515 | self.student['studycourse'].current_verdict = 'D' |
---|
| 516 | self.assertEqual(utils.getReturningData(self.student),(2005, 100)) |
---|
| 517 | return |
---|
[8267] | 518 | |
---|
[9006] | 519 | def test_set_returning_data(self): |
---|
| 520 | # Student is in level 100, session 2004 with verdict A |
---|
| 521 | utils = getUtility(IStudentsUtils) |
---|
| 522 | |
---|
| 523 | utils.setReturningData(self.student) |
---|
| 524 | self.assertEqual(self.student['studycourse'].current_session, 2005) |
---|
| 525 | self.assertEqual(self.student['studycourse'].current_level, 200) |
---|
| 526 | |
---|
| 527 | self.student['studycourse'].current_session = 2004 |
---|
| 528 | self.student['studycourse'].current_level = 100 |
---|
| 529 | self.student['studycourse'].current_verdict = 'C' |
---|
| 530 | utils.setReturningData(self.student) |
---|
| 531 | self.assertEqual(self.student['studycourse'].current_session, 2005) |
---|
| 532 | self.assertEqual(self.student['studycourse'].current_level, 110) |
---|
| 533 | |
---|
| 534 | self.student['studycourse'].current_session = 2004 |
---|
| 535 | self.student['studycourse'].current_level = 100 |
---|
| 536 | self.student['studycourse'].current_verdict = 'D' |
---|
| 537 | utils.setReturningData(self.student) |
---|
| 538 | self.assertEqual(self.student['studycourse'].current_session, 2005) |
---|
| 539 | self.assertEqual(self.student['studycourse'].current_level, 100) |
---|
| 540 | return |
---|
| 541 | |
---|
[8598] | 542 | def test_set_payment_details(self): |
---|
[8320] | 543 | self.app['configuration']['2004'].gown_fee = 150.0 |
---|
| 544 | self.app['configuration']['2004'].transfer_fee = 90.0 |
---|
| 545 | self.app['configuration']['2004'].booking_fee = 150.0 |
---|
| 546 | self.app['configuration']['2004'].maint_fee = 180.0 |
---|
[9206] | 547 | |
---|
| 548 | configuration = createObject('waeup.SessionConfiguration') |
---|
| 549 | configuration.academic_session = 2000 |
---|
| 550 | self.app['configuration'].addSessionConfiguration(configuration) |
---|
| 551 | configuration2 = createObject('waeup.SessionConfiguration') |
---|
| 552 | configuration2.academic_session = 2002 |
---|
| 553 | self.app['configuration'].addSessionConfiguration(configuration2) |
---|
| 554 | configuration3 = createObject('waeup.SessionConfiguration') |
---|
| 555 | configuration3.academic_session = 2003 |
---|
| 556 | self.app['configuration'].addSessionConfiguration(configuration3) |
---|
[9522] | 557 | configuration4 = createObject('waeup.SessionConfiguration') |
---|
| 558 | configuration4.academic_session = 2005 |
---|
| 559 | self.app['configuration'].addSessionConfiguration(configuration4) |
---|
[8320] | 560 | utils = getUtility(IStudentsUtils) |
---|
[9206] | 561 | self.student['studycourse'].entry_session = 2002 |
---|
[9152] | 562 | self.student.nationality = u'NG' |
---|
| 563 | |
---|
| 564 | error, payment = utils.setPaymentDetails('schoolfee', |
---|
[15666] | 565 | self.student, None, None, None) |
---|
[8598] | 566 | self.assertEqual(payment, None) |
---|
[9520] | 567 | # Student is in state 'created' and can thus not pay. |
---|
[9152] | 568 | self.assertTrue(u'Amount could not be determined.' in error) |
---|
[8598] | 569 | |
---|
[9206] | 570 | # Previous session must be valid. |
---|
| 571 | error, payment = utils.setPaymentDetails('schoolfee', |
---|
[15666] | 572 | self.student, 2000, 300, None) |
---|
[9206] | 573 | self.assertEqual(payment, None) |
---|
| 574 | self.assertTrue(u'The previous session must not fall below' in error) |
---|
| 575 | error, payment = utils.setPaymentDetails('schoolfee', |
---|
[15666] | 576 | self.student, 2005, 300, None) |
---|
[9206] | 577 | self.assertEqual(payment, None) |
---|
| 578 | self.assertTrue(u'This is not a previous session' in error) |
---|
| 579 | |
---|
[9520] | 580 | # Previous session schoolfee payment; fresh and returning |
---|
[9157] | 581 | # are distinguished by their entry_level |
---|
[9152] | 582 | error, payment = utils.setPaymentDetails('schoolfee', |
---|
[15666] | 583 | self.student, 2002, 300, None) |
---|
[17457] | 584 | self.assertEqual(payment.amount_auth, 63000.0) |
---|
[9206] | 585 | self.assertEqual(payment.p_session, 2002) |
---|
[9152] | 586 | self.assertEqual(payment.p_level, 300) |
---|
| 587 | self.assertFalse(payment.p_current) |
---|
| 588 | error, payment = utils.setPaymentDetails('schoolfee', |
---|
[15666] | 589 | self.student, 2003, 300, None) |
---|
[17457] | 590 | self.assertEqual(payment.amount_auth, 26800.0) |
---|
[9206] | 591 | self.assertEqual(payment.p_session, 2003) |
---|
[9152] | 592 | self.assertEqual(payment.p_level, 300) |
---|
| 593 | self.assertFalse(payment.p_current) |
---|
| 594 | |
---|
[9520] | 595 | # Current schoolfee payment; fresh and returning |
---|
[9157] | 596 | # are distinguished by their state |
---|
[8598] | 597 | IWorkflowState(self.student).setState('cleared') |
---|
[9152] | 598 | error, payment = utils.setPaymentDetails('schoolfee', |
---|
[15666] | 599 | self.student, None, None, None) |
---|
[8598] | 600 | self.assertEqual(payment.p_level, 100) |
---|
| 601 | self.assertEqual(payment.p_session, 2004) |
---|
[17457] | 602 | self.assertEqual(payment.amount_auth, 63000.0) |
---|
[8598] | 603 | self.assertEqual(payment.p_item, u'CERT1') |
---|
| 604 | self.assertEqual(error, None) |
---|
[9152] | 605 | self.assertTrue(payment.p_current) |
---|
[8598] | 606 | |
---|
[8959] | 607 | # Add penalty fee ... |
---|
| 608 | # ... for cleared |
---|
[13756] | 609 | self.app['configuration']['2004'].penalty_ug_ft = 99.0 |
---|
[8959] | 610 | # ... for returning |
---|
[13756] | 611 | self.app['configuration']['2005'].penalty_ug_ft = 88.0 |
---|
[9152] | 612 | error, payment = utils.setPaymentDetails('schoolfee', |
---|
[15666] | 613 | self.student, None, None, None) |
---|
[17457] | 614 | self.assertEqual(payment.amount_auth, 63099.0) |
---|
[8676] | 615 | |
---|
[8598] | 616 | IWorkflowState(self.student).setState('returning') |
---|
[9570] | 617 | |
---|
| 618 | #error, payment = utils.setPaymentDetails('schoolfee', |
---|
[15666] | 619 | # self.student, None, None, None) |
---|
[9570] | 620 | #self.assertTrue( |
---|
| 621 | # u'You have not yet paid your current/active session.' in error) |
---|
| 622 | ## Ok, that means we have to add paid payment ticket first. |
---|
| 623 | #payment = createObject('waeup.StudentOnlinePayment') |
---|
| 624 | #payment.p_category = u'schoolfee' |
---|
| 625 | #payment.p_session = self.student.current_session |
---|
| 626 | #payment.p_item = u'My Certificate' |
---|
| 627 | #payment.p_id = u'anyid' |
---|
| 628 | #payment.p_state = u'paid' |
---|
| 629 | #self.student['payments']['anykey'] = payment |
---|
| 630 | |
---|
[9152] | 631 | error, payment = utils.setPaymentDetails('schoolfee', |
---|
[15666] | 632 | self.student, None, None, None) |
---|
[8598] | 633 | self.assertEqual(payment.p_level, 200) |
---|
| 634 | self.assertEqual(payment.p_session, 2005) |
---|
[17457] | 635 | self.assertEqual(payment.amount_auth, 26888.0) |
---|
[8598] | 636 | self.assertEqual(payment.p_item, u'CERT1') |
---|
| 637 | self.assertEqual(error, None) |
---|
[9520] | 638 | |
---|
[14893] | 639 | # Old returning students may pay less. |
---|
[17457] | 640 | #self.certificate.school_fee_2 = 50000.0 |
---|
| 641 | #self.certificate.custom_float_2 = 30000.0 |
---|
[14892] | 642 | error, payment = utils.setPaymentDetails( |
---|
[15666] | 643 | 'schoolfee', self.student, None, None, None) |
---|
[17457] | 644 | self.assertEqual(payment.amount_auth, 26888.0) |
---|
[14892] | 645 | |
---|
[9520] | 646 | # Staff members pay less. |
---|
[9006] | 647 | self.student.is_staff = True |
---|
[9152] | 648 | error, payment = utils.setPaymentDetails('schoolfee', |
---|
[15666] | 649 | self.student, None, None, None) |
---|
[9006] | 650 | self.assertEqual(payment.p_level, 200) |
---|
| 651 | self.assertEqual(payment.p_session, 2005) |
---|
[17457] | 652 | self.assertEqual(payment.amount_auth, 13488.0) |
---|
[9006] | 653 | self.assertEqual(payment.p_item, u'CERT1') |
---|
| 654 | self.assertEqual(error, None) |
---|
| 655 | |
---|
[9520] | 656 | # Foreigners pay more. |
---|
[9006] | 657 | IWorkflowState(self.student).setState('cleared') |
---|
| 658 | self.student.is_staff = False |
---|
| 659 | self.student.nationality = u'DE' |
---|
[9152] | 660 | error, payment = utils.setPaymentDetails( |
---|
[15666] | 661 | 'schoolfee', self.student, None, None, None) |
---|
[9006] | 662 | self.assertEqual(payment.p_level, 100) |
---|
| 663 | self.assertEqual(payment.p_session, 2004) |
---|
[17457] | 664 | self.assertEqual(payment.amount_auth, 300099.0) |
---|
[9006] | 665 | self.assertEqual(payment.p_item, u'CERT1') |
---|
| 666 | self.assertEqual(error, None) |
---|
| 667 | IWorkflowState(self.student).setState('returning') |
---|
| 668 | self.student.is_staff = False |
---|
[9152] | 669 | error, payment = utils.setPaymentDetails( |
---|
[15666] | 670 | 'schoolfee', self.student, None, None, None) |
---|
[9006] | 671 | self.assertEqual(payment.p_level, 200) |
---|
| 672 | self.assertEqual(payment.p_session, 2005) |
---|
[17457] | 673 | self.assertEqual(payment.amount_auth, 277088.0) |
---|
[9006] | 674 | self.assertEqual(payment.p_item, u'CERT1') |
---|
| 675 | self.assertEqual(error, None) |
---|
| 676 | |
---|
[9513] | 677 | # In Uniben students can pay school fee in all states no matter |
---|
| 678 | # if they are ug or pg students. |
---|
[14857] | 679 | # diabled on 02/10/2017, see ticket 1108 |
---|
| 680 | #IWorkflowState(self.student).setState('school fee paid') |
---|
| 681 | #self.student.is_staff = False |
---|
| 682 | #self.student.nationality = u'NG' |
---|
| 683 | #self.certificate.school_fee_2 = 10000.0 |
---|
| 684 | #error, payment = utils.setPaymentDetails( |
---|
[15666] | 685 | # 'schoolfee', self.student, None, None, None) |
---|
[14857] | 686 | #self.assertEqual(payment.p_level, None) |
---|
| 687 | #self.assertEqual(payment.p_session, 2005) |
---|
| 688 | #self.assertEqual(payment.amount_auth, 10088.0) |
---|
| 689 | #self.assertEqual(payment.p_item, u'CERT1') |
---|
| 690 | #self.assertEqual(error, None) |
---|
| 691 | #IWorkflowState(self.student).setState('courses registered') |
---|
| 692 | #self.certificate.study_mode = 'special_pg_pt' |
---|
| 693 | #error, payment = utils.setPaymentDetails( |
---|
[15666] | 694 | # 'schoolfee', self.student, None, None, None) |
---|
[14857] | 695 | #self.assertEqual(payment.p_level, None) |
---|
| 696 | #self.assertEqual(payment.p_session, 2005) |
---|
| 697 | #self.assertEqual(payment.amount_auth, 10000.0) |
---|
| 698 | #self.assertEqual(payment.p_item, u'CERT1') |
---|
| 699 | #self.assertEqual(error, None) |
---|
| 700 | #IWorkflowState(self.student).setState('courses validated') |
---|
| 701 | #error, payment = utils.setPaymentDetails( |
---|
[15666] | 702 | # 'schoolfee', self.student, None, None, None) |
---|
[14857] | 703 | #self.assertEqual(payment.p_level, None) |
---|
| 704 | #self.assertEqual(payment.p_session, 2005) |
---|
| 705 | #self.assertEqual(payment.amount_auth, 10000.0) |
---|
| 706 | #self.assertEqual(payment.p_item, u'CERT1') |
---|
| 707 | #self.assertEqual(error, None) |
---|
[9251] | 708 | |
---|
[9152] | 709 | error, payment = utils.setPaymentDetails('clearance', |
---|
[15666] | 710 | self.student, None, None, None) |
---|
[8598] | 711 | self.assertEqual(payment.p_level, 100) |
---|
| 712 | self.assertEqual(payment.p_session, 2004) |
---|
[14897] | 713 | self.assertEqual(payment.amount_auth, 60000.0) |
---|
[8598] | 714 | self.assertEqual(payment.p_item, u'CERT1') |
---|
| 715 | self.assertEqual(error, None) |
---|
| 716 | |
---|
[9152] | 717 | error, payment = utils.setPaymentDetails('gown', |
---|
[15666] | 718 | self.student, None, None, None) |
---|
[8598] | 719 | self.assertEqual(payment.p_level, 100) |
---|
| 720 | self.assertEqual(payment.p_session, 2004) |
---|
| 721 | self.assertEqual(payment.amount_auth, 150.0) |
---|
| 722 | self.assertEqual(payment.p_item, u'') |
---|
| 723 | self.assertEqual(error, None) |
---|
| 724 | |
---|
[13251] | 725 | bedticket = BedTicket() |
---|
| 726 | bedticket.booking_session = 2004 |
---|
| 727 | bedticket.bed_type = u'any bed type' |
---|
| 728 | bedticket.bed = self.app['hostels']['hall-1']['hall-1_A_101_A'] |
---|
| 729 | bedticket.bed_coordinates = u'My bed coordinates' |
---|
| 730 | self.student['accommodation'].addBedTicket(bedticket) |
---|
| 731 | |
---|
| 732 | error, payment = utils.setPaymentDetails('hostel_maintenance', |
---|
[15666] | 733 | self.student, None, None, None) |
---|
[13251] | 734 | self.assertEqual(payment.p_level, 100) |
---|
| 735 | self.assertEqual(payment.p_session, 2004) |
---|
| 736 | self.assertEqual(payment.amount_auth, 876.0) |
---|
| 737 | self.assertEqual(payment.p_item, u'My bed coordinates') |
---|
| 738 | self.assertEqual(error, None) |
---|
| 739 | |
---|
[14898] | 740 | #self.certificate.study_mode = 'ug_ft' |
---|
| 741 | #error, payment = utils.setPaymentDetails('bed_allocation', |
---|
[15666] | 742 | # self.student, None, None, None) |
---|
[14898] | 743 | #self.assertTrue(u'Amount could not be determined.' in error) |
---|
| 744 | #self.student['studycourse'].current_session = 2004 |
---|
| 745 | #self.student['studycourse'].entry_session = 2004 |
---|
| 746 | #self.student['studycourse'].current_level = 100 |
---|
| 747 | #error, payment = utils.setPaymentDetails('bed_allocation', |
---|
[15666] | 748 | # self.student, None, None, None) |
---|
[14898] | 749 | #self.assertEqual(payment.p_level, 100) |
---|
| 750 | #self.assertEqual(payment.p_session, 2004) |
---|
| 751 | #self.assertEqual(payment.amount_auth, 650.0) # plus 500 student union |
---|
| 752 | #self.assertEqual(payment.p_item, u'regular_male_fr') |
---|
| 753 | #self.assertEqual(error, None) |
---|
[13251] | 754 | |
---|
[13777] | 755 | self.certificate.study_mode = 'pg_ft' |
---|
| 756 | error, payment = utils.setPaymentDetails('bed_allocation', |
---|
[15666] | 757 | self.student, None, None, None) |
---|
[15314] | 758 | self.assertEqual(error, u'Select your favoured hostel first.') |
---|
| 759 | self.student['accommodation'].desired_hostel = u'no' |
---|
| 760 | error, payment = utils.setPaymentDetails('bed_allocation', |
---|
[15666] | 761 | self.student, None, None, None) |
---|
[13777] | 762 | self.assertEqual(payment.p_level, 100) |
---|
| 763 | self.assertEqual(payment.p_session, 2004) |
---|
[15002] | 764 | self.assertEqual(payment.amount_auth, 650.0) |
---|
[13777] | 765 | self.assertEqual(payment.p_item, u'pg_male_all') |
---|
| 766 | self.assertEqual(error, None) |
---|
| 767 | |
---|
[13251] | 768 | #error, payment = utils.setPaymentDetails('hostel_application', |
---|
[15666] | 769 | # self.student, None, None, None) |
---|
[12566] | 770 | #self.assertEqual(payment.p_level, 100) |
---|
| 771 | #self.assertEqual(payment.p_session, 2004) |
---|
[13251] | 772 | #self.assertEqual(payment.amount_auth, 1000.0) |
---|
[12566] | 773 | #self.assertEqual(payment.p_item, u'') |
---|
| 774 | #self.assertEqual(error, None) |
---|
[8598] | 775 | |
---|
[13251] | 776 | #payment.approve() |
---|
| 777 | #self.student['payments'][payment.p_id] = payment |
---|
| 778 | |
---|
| 779 | #error, payment = utils.setPaymentDetails('tempmaint_1', |
---|
[15666] | 780 | # self.student, None, None, None) |
---|
[12566] | 781 | #self.assertEqual(payment.p_level, 100) |
---|
| 782 | #self.assertEqual(payment.p_session, 2004) |
---|
[13251] | 783 | #self.assertEqual(payment.amount_auth, 8150.0) |
---|
| 784 | #self.assertEqual(payment.p_item, u'Hall 1-4 M/F Ekehuan') |
---|
[12566] | 785 | #self.assertEqual(error, None) |
---|
| 786 | |
---|
[13251] | 787 | #error, payment = utils.setPaymentDetails('tempmaint_2', |
---|
[15666] | 788 | # self.student, None, None, None) |
---|
[13251] | 789 | #self.assertEqual(payment.p_level, 100) |
---|
| 790 | #self.assertEqual(payment.p_session, 2004) |
---|
| 791 | #self.assertEqual(payment.amount_auth, 12650.0) |
---|
| 792 | #self.assertEqual(payment.p_item, u'Hall 5 M/F') |
---|
| 793 | #self.assertEqual(error, None) |
---|
[8598] | 794 | |
---|
[13251] | 795 | #error, payment = utils.setPaymentDetails('tempmaint_3', |
---|
[15666] | 796 | # self.student, None, None, None) |
---|
[13251] | 797 | #self.assertEqual(payment.p_level, 100) |
---|
| 798 | #self.assertEqual(payment.p_session, 2004) |
---|
| 799 | #self.assertEqual(payment.amount_auth, 9650.0) |
---|
| 800 | #self.assertEqual(payment.p_item, u'Clinical Hostel') |
---|
| 801 | #self.assertEqual(error, None) |
---|
[12566] | 802 | |
---|
[9152] | 803 | error, payment = utils.setPaymentDetails('transfer', |
---|
[15666] | 804 | self.student, None, None, None) |
---|
[8598] | 805 | self.assertEqual(payment.p_level, 100) |
---|
| 806 | self.assertEqual(payment.p_session, 2004) |
---|
| 807 | self.assertEqual(payment.amount_auth, 90.0) |
---|
| 808 | self.assertEqual(payment.p_item, u'') |
---|
| 809 | self.assertEqual(error, None) |
---|
[9210] | 810 | return |
---|
| 811 | |
---|
| 812 | def test_edit_level_by_co(self): |
---|
| 813 | # Create clearance officer |
---|
[15307] | 814 | self.app['users'].addUser('mrclear', 'mrClearsecret1') |
---|
[9210] | 815 | self.app['users']['mrclear'].email = 'mrclear@foo.ng' |
---|
| 816 | self.app['users']['mrclear'].title = 'Carlo Pitter' |
---|
| 817 | # Assign local ClearanceOfficer role |
---|
| 818 | department = self.app['faculties']['fac1']['dep1'] |
---|
| 819 | prmlocal = IPrincipalRoleManager(department) |
---|
| 820 | prmlocal.assignRoleToPrincipal('waeup.local.ClearanceOfficer', 'mrclear') |
---|
| 821 | notify(LocalRoleSetEvent( |
---|
| 822 | department, 'waeup.local.ClearanceOfficer', 'mrclear', granted=True)) |
---|
| 823 | IWorkflowState(self.student).setState('clearance started') |
---|
| 824 | # Login as clearance officer |
---|
| 825 | self.browser.open(self.login_path) |
---|
| 826 | self.browser.getControl(name="form.login").value = 'mrclear' |
---|
[15307] | 827 | self.browser.getControl(name="form.password").value = 'mrClearsecret1' |
---|
[9210] | 828 | self.browser.getControl("Login").click() |
---|
| 829 | self.assertMatches('...You logged in...', self.browser.contents) |
---|
| 830 | # Only in state clearance requested the CO does see the |
---|
| 831 | # 'Edit level' button ... |
---|
| 832 | self.browser.open(self.studycourse_path) |
---|
| 833 | self.assertFalse('Edit level' in self.browser.contents) |
---|
| 834 | # ... and can open the edit_level view |
---|
| 835 | self.browser.open(self.studycourse_path + '/edit_level') |
---|
| 836 | self.assertMatches('...is locked...', self.browser.contents) |
---|
| 837 | self.assertEqual(self.browser.url, self.studycourse_path) |
---|
| 838 | IWorkflowInfo(self.student).fireTransition('request_clearance') |
---|
| 839 | self.browser.open(self.studycourse_path) |
---|
| 840 | self.assertTrue('Edit level' in self.browser.contents) |
---|
| 841 | self.browser.getLink("Edit level").click() |
---|
| 842 | self.browser.getControl(name="form.current_level").value = ['200'] |
---|
| 843 | self.browser.getControl("Save").click() |
---|
| 844 | self.assertMatches('...has been saved...', self.browser.contents) |
---|
| 845 | self.assertEqual(self.student.current_level, 200) |
---|
[9281] | 846 | |
---|
| 847 | def test_postgraduate_student_access(self): |
---|
| 848 | self.certificate.study_mode = 'special_pg_pt' |
---|
| 849 | self.certificate.start_level = 700 |
---|
| 850 | self.certificate.end_level = 800 |
---|
| 851 | self.student['studycourse'].current_level = 700 |
---|
| 852 | IWorkflowState(self.student).setState('school fee paid') |
---|
| 853 | self.browser.open(self.login_path) |
---|
| 854 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 855 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 856 | self.browser.getControl("Login").click() |
---|
| 857 | self.assertTrue( |
---|
[17298] | 858 | 'Did you know that with' in self.browser.contents) |
---|
[9281] | 859 | # Now students can add the current study level |
---|
| 860 | self.browser.getLink("Study Course").click() |
---|
| 861 | self.browser.getLink("Add course list").click() |
---|
| 862 | self.assertMatches('...Add current level 700...', |
---|
| 863 | self.browser.contents) |
---|
| 864 | self.browser.getControl("Create course list now").click() |
---|
[9831] | 865 | # A level with no course ticket was created |
---|
[9281] | 866 | self.assertEqual(self.student['studycourse']['700'].number_of_tickets, 0) |
---|
| 867 | self.browser.getLink("700").click() |
---|
| 868 | self.browser.getLink("Edit course list").click() |
---|
[9902] | 869 | self.browser.getLink("here").click() |
---|
[9281] | 870 | self.browser.getControl(name="form.course").value = ['COURSE1'] |
---|
[9831] | 871 | # Non-final year students can't add ticket with 51 credits |
---|
| 872 | self.app['faculties']['fac1']['dep1'].courses['COURSE1'].credits = 51 |
---|
[9281] | 873 | self.browser.getControl("Add course ticket").click() |
---|
[14588] | 874 | self.assertMatches('...Maximum credits exceeded...', |
---|
[9831] | 875 | self.browser.contents) |
---|
| 876 | # Final year students can't add ticket with 52 credits ... |
---|
| 877 | self.app['faculties']['fac1']['dep1'].courses['COURSE1'].credits = 52 |
---|
| 878 | self.student['studycourse'].certificate.end_level = 700 |
---|
| 879 | self.browser.getControl("Add course ticket").click() |
---|
[14588] | 880 | self.assertMatches('...Maximum credits exceeded...', |
---|
[9831] | 881 | self.browser.contents) |
---|
| 882 | # ... but with 51 credits |
---|
| 883 | self.app['faculties']['fac1']['dep1'].courses['COURSE1'].credits = 51 |
---|
| 884 | self.browser.getControl("Add course ticket").click() |
---|
[9281] | 885 | self.assertMatches('...Successfully added COURSE1...', |
---|
| 886 | self.browser.contents) |
---|
[9831] | 887 | # Non-final year special postgraduate students can't register |
---|
| 888 | # course lists if their total credits are 51 and thus exceed 50 ... |
---|
| 889 | self.student['studycourse'].certificate.end_level = 800 |
---|
[9281] | 890 | self.browser.getControl("Register course list").click() |
---|
[14588] | 891 | self.assertMatches('...Maximum credits exceeded...', |
---|
[9831] | 892 | self.browser.contents) |
---|
| 893 | # ... but final year students can |
---|
| 894 | self.student['studycourse'].certificate.end_level = 700 |
---|
| 895 | self.browser.getControl("Register course list").click() |
---|
[9281] | 896 | self.assertMatches('...Course list has been registered...', |
---|
| 897 | self.browser.contents) |
---|
| 898 | self.assertEqual(self.student.state, 'courses registered') |
---|
| 899 | return |
---|
[9709] | 900 | |
---|
| 901 | def test_login(self): |
---|
| 902 | # If suspended_comment is set this message will be flashed instead |
---|
| 903 | self.student.suspended_comment = u'Aetsch baetsch!' |
---|
| 904 | self.student.suspended = True |
---|
| 905 | self.browser.open(self.login_path) |
---|
| 906 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 907 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 908 | self.browser.getControl("Login").click() |
---|
| 909 | # Uniben does not display suspended_comment |
---|
| 910 | self.assertMatches( |
---|
[11317] | 911 | '...<div class="alert alert-warning">Your account has been deactivated.</div>...', |
---|
[9709] | 912 | self.browser.contents) |
---|
[11069] | 913 | self.student.suspended = False |
---|
| 914 | |
---|
| 915 | def test_activate_deactivate_buttons(self): |
---|
| 916 | self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') |
---|
| 917 | self.browser.open(self.student_path) |
---|
| 918 | self.browser.getLink("Deactivate").click() |
---|
| 919 | self.assertTrue( |
---|
| 920 | 'Student account has been deactivated.' in self.browser.contents) |
---|
| 921 | self.assertTrue( |
---|
| 922 | 'Base Data (account deactivated)' in self.browser.contents) |
---|
| 923 | self.assertTrue(self.student.suspended) |
---|
| 924 | self.browser.getLink("Activate").click() |
---|
| 925 | self.assertTrue( |
---|
| 926 | 'Student account has been activated.' in self.browser.contents) |
---|
| 927 | self.assertFalse( |
---|
| 928 | 'Base Data (account deactivated)' in self.browser.contents) |
---|
| 929 | self.assertFalse(self.student.suspended) |
---|
| 930 | # History messages have been added ... |
---|
| 931 | self.browser.getLink("History").click() |
---|
| 932 | # User is undisclosed |
---|
| 933 | self.assertTrue( |
---|
| 934 | 'Student account deactivated<br />' in self.browser.contents) |
---|
| 935 | self.assertTrue( |
---|
| 936 | 'Student account activated<br />' in self.browser.contents) |
---|
| 937 | # ... and actions have been logged. |
---|
| 938 | logfile = os.path.join( |
---|
| 939 | self.app['datacenter'].storage, 'logs', 'students.log') |
---|
| 940 | logcontent = open(logfile).read() |
---|
[13063] | 941 | self.assertTrue('zope.mgr - waeup.uniben.students.browser.CustomStudentDeactivateView - ' |
---|
[11069] | 942 | 'B1000000 - account deactivated' in logcontent) |
---|
[13063] | 943 | self.assertTrue('zope.mgr - waeup.uniben.students.browser.CustomStudentActivateView - ' |
---|
[11317] | 944 | 'B1000000 - account activated' in logcontent) |
---|
[11611] | 945 | |
---|
| 946 | def test_manage_upload_fpm_file(self): |
---|
| 947 | self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') |
---|
| 948 | self.browser.open(self.manage_clearance_path) |
---|
| 949 | image = open(SAMPLE_FPM, 'rb') |
---|
| 950 | ctrl = self.browser.getControl(name='leftthumbprintupload') |
---|
| 951 | file_ctrl = ctrl.mech_control |
---|
| 952 | file_ctrl.add_file(image, filename='thumbprint.fpm') |
---|
| 953 | self.browser.getControl( |
---|
| 954 | name='upload_leftthumbprintupload').click() |
---|
| 955 | self.assertTrue( |
---|
| 956 | 'File finger1.fpm uploaded.' in self.browser.contents) |
---|
| 957 | self.assertTrue( |
---|
| 958 | 'http://localhost/app/students/B1000000/finger1.fpm' |
---|
| 959 | in self.browser.contents) |
---|
| 960 | self.browser.getControl( |
---|
| 961 | name='delete_leftthumbprintupload').click() |
---|
| 962 | self.assertTrue( |
---|
| 963 | 'finger1.fpm deleted' |
---|
[11773] | 964 | in self.browser.contents) |
---|
| 965 | |
---|
| 966 | def test_handle_clearance_by_co(self): |
---|
| 967 | # Create clearance officer |
---|
[15307] | 968 | self.app['users'].addUser('mrclear', 'mrClearsecret1') |
---|
[11773] | 969 | self.app['users']['mrclear'].email = 'mrclear@foo.ng' |
---|
| 970 | self.app['users']['mrclear'].title = 'Carlo Pitter' |
---|
| 971 | department = self.app['faculties']['fac1']['dep1'] |
---|
| 972 | prmlocal = IPrincipalRoleManager(department) |
---|
| 973 | prmlocal.assignRoleToPrincipal('waeup.local.ClearanceOfficer', 'mrclear') |
---|
| 974 | notify(LocalRoleSetEvent( |
---|
| 975 | department, 'waeup.local.ClearanceOfficer', 'mrclear', granted=True)) |
---|
| 976 | IWorkflowState(self.student).setState('clearance requested') |
---|
| 977 | # Login as clearance officer |
---|
| 978 | self.browser.open(self.login_path) |
---|
| 979 | self.browser.getControl(name="form.login").value = 'mrclear' |
---|
[15307] | 980 | self.browser.getControl(name="form.password").value = 'mrClearsecret1' |
---|
[11773] | 981 | self.browser.getControl("Login").click() |
---|
| 982 | self.assertMatches('...You logged in...', self.browser.contents) |
---|
| 983 | # CO can view the student ... |
---|
| 984 | self.browser.open(self.clearance_path) |
---|
| 985 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 986 | self.assertEqual(self.browser.url, self.clearance_path) |
---|
| 987 | # Clearance is disabled for this session for ug students ... |
---|
| 988 | self.browser.open(self.clearance_path) |
---|
| 989 | self.assertFalse('Clear student' in self.browser.contents) |
---|
| 990 | self.browser.open(self.student_path + '/clear') |
---|
| 991 | self.assertTrue('Clearance is disabled for this session' |
---|
| 992 | in self.browser.contents) |
---|
| 993 | # ... but not for |
---|
| 994 | self.certificate.study_mode = 'pg_ft' |
---|
| 995 | self.browser.open(self.clearance_path) |
---|
| 996 | self.assertTrue('Clear student' in self.browser.contents) |
---|
| 997 | self.browser.open(self.student_path + '/clear') |
---|
[12845] | 998 | self.assertTrue('Student has been cleared' in self.browser.contents) |
---|
| 999 | |
---|
| 1000 | def test_transcripts(self): |
---|
| 1001 | studylevel = createObject(u'waeup.StudentStudyLevel') |
---|
[16171] | 1002 | IWorkflowState(self.student).setState('transcript validated') |
---|
[12845] | 1003 | studylevel.level = 100 |
---|
| 1004 | studylevel.level_session = 2005 |
---|
| 1005 | self.student['studycourse'].entry_mode = 'ug_ft' |
---|
| 1006 | self.student['studycourse'].addStudentStudyLevel( |
---|
| 1007 | self.certificate, studylevel) |
---|
| 1008 | studylevel2 = createObject(u'waeup.StudentStudyLevel') |
---|
| 1009 | studylevel2.level = 110 |
---|
| 1010 | studylevel2.level_session = 2006 |
---|
| 1011 | self.student['studycourse'].addStudentStudyLevel( |
---|
| 1012 | self.certificate, studylevel2) |
---|
| 1013 | # Add second course (COURSE has been added automatically) |
---|
| 1014 | courseticket = createObject('waeup.CourseTicket') |
---|
| 1015 | courseticket.code = 'ANYCODE' |
---|
| 1016 | courseticket.title = u'Any TITLE' |
---|
| 1017 | courseticket.credits = 13 |
---|
| 1018 | courseticket.score = 66 |
---|
| 1019 | courseticket.semester = 1 |
---|
| 1020 | courseticket.dcode = u'ANYDCODE' |
---|
| 1021 | courseticket.fcode = u'ANYFCODE' |
---|
| 1022 | self.student['studycourse']['110']['COURSE2'] = courseticket |
---|
| 1023 | self.student['studycourse']['100']['COURSE1'].score = 55 |
---|
| 1024 | self.assertEqual(self.student['studycourse']['100'].gpa_params_rectified[0], 3.0) |
---|
| 1025 | self.assertEqual(self.student['studycourse']['110'].gpa_params_rectified[0], 4.0) |
---|
| 1026 | # Get transcript data |
---|
| 1027 | td = self.student['studycourse'].getTranscriptData() |
---|
| 1028 | self.assertEqual(td[0][0]['level_key'], '100') |
---|
| 1029 | self.assertEqual(td[0][0]['sgpa'], 3.0) |
---|
| 1030 | self.assertEqual(td[0][0]['level'].level, 100) |
---|
| 1031 | self.assertEqual(td[0][0]['level'].level_session, 2005) |
---|
| 1032 | self.assertEqual(td[0][0]['tickets_1'][0].code, 'COURSE1') |
---|
| 1033 | self.assertEqual(td[0][1]['level_key'], '110') |
---|
| 1034 | self.assertEqual(td[0][1]['sgpa'], 4.0) |
---|
| 1035 | self.assertEqual(td[0][1]['level'].level, 110) |
---|
| 1036 | self.assertEqual(td[0][1]['level'].level_session, 2006) |
---|
| 1037 | self.assertEqual(td[0][1]['tickets_1'][0].code, 'ANYCODE') |
---|
[14421] | 1038 | self.assertEqual(td[1], 3.5652173913043477) |
---|
[16906] | 1039 | self.browser.open(self.login_path) |
---|
| 1040 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 1041 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 1042 | self.browser.getControl("Login").click() |
---|
[16946] | 1043 | # Students can't open the pdf transcript ... |
---|
| 1044 | transcript_path = self.student_path + '/studycourse/transcript' |
---|
| 1045 | self.assertRaises( |
---|
| 1046 | Unauthorized, self.browser.open, transcript_path) |
---|
| 1047 | # ... but managers can |
---|
| 1048 | self.browser.open(self.student_path) |
---|
| 1049 | self.browser.getLink("Logout").click() |
---|
| 1050 | self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') |
---|
| 1051 | self.browser.open(transcript_path) |
---|
[12845] | 1052 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 1053 | self.assertTrue('Transcript' in self.browser.contents) |
---|
| 1054 | self.browser.open(self.student_path + '/studycourse/transcript.pdf') |
---|
| 1055 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 1056 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
| 1057 | path = os.path.join(samples_dir(), 'transcript.pdf') |
---|
| 1058 | open(path, 'wb').write(self.browser.contents) |
---|
[13251] | 1059 | print "Sample PDF transcript.pdf written to %s" % path |
---|
| 1060 | |
---|
| 1061 | def test_student_accommodation(self): |
---|
[15251] | 1062 | self.app['hostels'].allocation_expiration = 7 |
---|
[15268] | 1063 | self.student['accommodation'].desired_hostel = u'hall-1' |
---|
[13283] | 1064 | bed = Bed() |
---|
| 1065 | bed.bed_id = u'hall-1_A_101_C' |
---|
| 1066 | bed.bed_number = 3 |
---|
| 1067 | bed.owner = NOT_OCCUPIED |
---|
| 1068 | bed.bed_type = u'regular_male_fi' |
---|
| 1069 | self.app['hostels']['hall-1'].addBed(bed) |
---|
[13251] | 1070 | self.browser.open(self.login_path) |
---|
| 1071 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 1072 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 1073 | self.browser.getControl("Login").click() |
---|
| 1074 | # Students can add online booking fee payment tickets and open the |
---|
| 1075 | # callback view (see test_manage_payments). |
---|
| 1076 | self.browser.getLink("Payments").click() |
---|
| 1077 | self.browser.getLink("Add current session payment ticket").click() |
---|
| 1078 | self.browser.getControl(name="form.p_category").value = ['bed_allocation'] |
---|
| 1079 | self.browser.getControl("Create ticket").click() |
---|
| 1080 | p_ticket = self.student['payments'].values()[0] |
---|
[15268] | 1081 | self.assertEqual(p_ticket.p_item, 'regular_male_fr (hall-1)') |
---|
[13251] | 1082 | p_ticket.approveStudentPayment() |
---|
| 1083 | # The new HOS-0 pin has been created. |
---|
| 1084 | self.assertEqual(len(self.app['accesscodes']['HOS-0']),1) |
---|
| 1085 | pin = self.app['accesscodes']['HOS-0'].keys()[0] |
---|
| 1086 | ac = self.app['accesscodes']['HOS-0'][pin] |
---|
| 1087 | parts = pin.split('-')[1:] |
---|
| 1088 | sfeseries, sfenumber = parts |
---|
| 1089 | # Students can use HOS code and book a bed space with it ... |
---|
| 1090 | self.browser.open(self.acco_path) |
---|
| 1091 | # ... but not if booking period has expired ... |
---|
| 1092 | self.app['hostels'].enddate = datetime.now(pytz.utc) |
---|
[13460] | 1093 | self.browser.getControl("Book accommodation").click() |
---|
[13251] | 1094 | self.assertMatches('...Outside booking period: ...', |
---|
| 1095 | self.browser.contents) |
---|
| 1096 | self.app['hostels'].enddate = datetime.now(pytz.utc) + timedelta(days=10) |
---|
| 1097 | # ... or student data are incomplete ... |
---|
| 1098 | self.student['studycourse'].current_level = None |
---|
[13460] | 1099 | self.browser.getControl("Book accommodation").click() |
---|
[13251] | 1100 | self.assertMatches('...Your data are incomplete...', |
---|
| 1101 | self.browser.contents) |
---|
[13283] | 1102 | self.student['studycourse'].current_level = 200 |
---|
| 1103 | # ... or student is not the an allowed state ... |
---|
[13460] | 1104 | self.browser.getControl("Book accommodation").click() |
---|
[13283] | 1105 | self.assertMatches('...You are in the wrong...', |
---|
| 1106 | self.browser.contents) |
---|
| 1107 | self.app['hostels'].accommodation_states = ['admitted', 'school fee paid'] |
---|
| 1108 | IWorkflowState(self.student).setState('school fee paid') |
---|
[13252] | 1109 | # ... or student has not appropriate verdict (Uniben only!) |
---|
[13283] | 1110 | self.student['studycourse'].entry_session = 2000 # non-fresh |
---|
| 1111 | self.student['studycourse'].current_level = 500 # final-year |
---|
[13252] | 1112 | self.student['studycourse'].current_verdict = 'C' |
---|
[13460] | 1113 | self.browser.getControl("Book accommodation").click() |
---|
[13252] | 1114 | self.assertMatches('...Your are not eligible...', |
---|
| 1115 | self.browser.contents) |
---|
[13309] | 1116 | self.student['studycourse'].previous_verdict = 'A' |
---|
[13460] | 1117 | self.browser.getControl("Book accommodation").click() |
---|
[13251] | 1118 | self.assertMatches('...Activation Code:...', |
---|
| 1119 | self.browser.contents) |
---|
| 1120 | # Student can't use faked ACs ... |
---|
| 1121 | self.browser.getControl(name="ac_series").value = u'nonsense' |
---|
| 1122 | self.browser.getControl(name="ac_number").value = sfenumber |
---|
| 1123 | self.browser.getControl("Create bed ticket").click() |
---|
| 1124 | self.assertMatches('...Activation code is invalid...', |
---|
| 1125 | self.browser.contents) |
---|
| 1126 | # ... or ACs owned by somebody else. |
---|
| 1127 | ac.owner = u'Anybody' |
---|
| 1128 | self.browser.getControl(name="ac_series").value = sfeseries |
---|
| 1129 | self.browser.getControl(name="ac_number").value = sfenumber |
---|
| 1130 | self.browser.getControl("Create bed ticket").click() |
---|
| 1131 | self.assertMatches('...You are not the owner of this access code...', |
---|
| 1132 | self.browser.contents) |
---|
| 1133 | # The bed remains empty. |
---|
[13283] | 1134 | bed = self.app['hostels']['hall-1']['hall-1_A_101_C'] |
---|
[13251] | 1135 | self.assertTrue(bed.owner == NOT_OCCUPIED) |
---|
| 1136 | ac.owner = self.student_id |
---|
| 1137 | self.browser.getControl(name="ac_series").value = sfeseries |
---|
| 1138 | self.browser.getControl(name="ac_number").value = sfenumber |
---|
| 1139 | self.browser.getControl("Create bed ticket").click() |
---|
[13296] | 1140 | self.assertMatches('...Hall 1, Block/Unit A, Room 101, Bed C...', |
---|
[13251] | 1141 | self.browser.contents) |
---|
| 1142 | # Bed has been allocated. |
---|
| 1143 | self.assertTrue(bed.owner == self.student_id) |
---|
| 1144 | # BedTicketAddPage is now blocked. |
---|
[13460] | 1145 | self.browser.getControl("Book accommodation").click() |
---|
[13251] | 1146 | self.assertMatches('...You already booked a bed space...', |
---|
| 1147 | self.browser.contents) |
---|
| 1148 | # The bed ticket displays the data correctly. |
---|
| 1149 | self.browser.open(self.acco_path + '/2004') |
---|
[13296] | 1150 | self.assertMatches('...Hall 1, Block/Unit A, Room 101, Bed C...', |
---|
[13251] | 1151 | self.browser.contents) |
---|
| 1152 | self.assertMatches('...2004/2005...', self.browser.contents) |
---|
[13283] | 1153 | self.assertMatches('...regular_male_fi...', self.browser.contents) |
---|
[13251] | 1154 | self.assertMatches('...%s...' % pin, self.browser.contents) |
---|
| 1155 | # Students can open the pdf slip. |
---|
| 1156 | self.browser.open(self.browser.url + '/bed_allocation_slip.pdf') |
---|
| 1157 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 1158 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
[13317] | 1159 | path = os.path.join(samples_dir(), 'bed_allocation_slip.pdf') |
---|
| 1160 | open(path, 'wb').write(self.browser.contents) |
---|
| 1161 | print "Sample PDF bed_allocation_slip.pdf written to %s" % path |
---|
[13251] | 1162 | # Students can't relocate themselves. |
---|
| 1163 | self.assertFalse('Relocate' in self.browser.contents) |
---|
| 1164 | relocate_path = self.acco_path + '/2004/relocate' |
---|
| 1165 | self.assertRaises( |
---|
| 1166 | Unauthorized, self.browser.open, relocate_path) |
---|
| 1167 | # Students can't see the Remove button and check boxes. |
---|
| 1168 | self.browser.open(self.acco_path) |
---|
| 1169 | self.assertFalse('Remove' in self.browser.contents) |
---|
| 1170 | self.assertFalse('val_id' in self.browser.contents) |
---|
| 1171 | # Students can pay maintenance fee now. |
---|
| 1172 | self.browser.open(self.payments_path) |
---|
| 1173 | self.browser.open(self.payments_path + '/addop') |
---|
| 1174 | self.browser.getControl(name="form.p_category").value = ['hostel_maintenance'] |
---|
| 1175 | self.browser.getControl("Create ticket").click() |
---|
| 1176 | self.assertMatches('...Payment ticket created...', |
---|
| 1177 | self.browser.contents) |
---|
| 1178 | # Maintennace fee is taken from the hostel object. |
---|
[13723] | 1179 | self.assertEqual(self.student['payments'].values()[1].amount_auth, 876.0) |
---|
[13251] | 1180 | # If the hostel's maintenance fee isn't set, the fee is |
---|
| 1181 | # taken from the session configuration object. |
---|
| 1182 | self.app['hostels']['hall-1'].maint_fee = 0.0 |
---|
| 1183 | self.browser.open(self.payments_path + '/addop') |
---|
| 1184 | self.browser.getControl(name="form.p_category").value = ['hostel_maintenance'] |
---|
| 1185 | self.browser.getControl("Create ticket").click() |
---|
[13723] | 1186 | self.assertEqual(self.student['payments'].values()[2].amount_auth, 987.0) |
---|
[15371] | 1187 | return |
---|
[15574] | 1188 | |
---|
| 1189 | def test_student_clearance(self): |
---|
| 1190 | # create some passport file for `student` |
---|
| 1191 | storage = getUtility(IExtFileStore) |
---|
| 1192 | image_path = os.path.join(os.path.dirname(__file__), 'test_image.jpg') |
---|
| 1193 | self.image_contents = open(image_path, 'rb').read() |
---|
| 1194 | file_id = IFileStoreNameChooser(self.student).chooseName( |
---|
| 1195 | attr='passport.jpg') |
---|
| 1196 | storage.createFile(file_id, StringIO(self.image_contents)) |
---|
| 1197 | IWorkflowInfo(self.student).fireTransition('admit') |
---|
| 1198 | self.browser.open(self.login_path) |
---|
| 1199 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 1200 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 1201 | self.browser.getControl("Login").click() |
---|
| 1202 | self.assertMatches( |
---|
[17298] | 1203 | '...Did you know that with...', self.browser.contents) |
---|
[15574] | 1204 | self.browser.getLink("Base Data").click() |
---|
| 1205 | self.browser.getLink("Download admission letter").click() |
---|
| 1206 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 1207 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
| 1208 | path = os.path.join(samples_dir(), 'admission_slip.pdf') |
---|
| 1209 | open(path, 'wb').write(self.browser.contents) |
---|
| 1210 | print "Sample PDF admission_slip.pdf written to %s" % path |
---|
| 1211 | self.browser.open(self.student_path + '/start_clearance') |
---|
| 1212 | # Regular students have to enter an access code |
---|
| 1213 | self.browser.getControl("Start clearance now").click() |
---|
| 1214 | self.assertTrue('Activation code is invalid' in self.browser.contents) |
---|
| 1215 | # DCOEM students can start clearance without access code |
---|
| 1216 | self.app['faculties']['fac1'].code = 'DCOEM' |
---|
| 1217 | self.browser.open(self.student_path + '/start_clearance') |
---|
| 1218 | self.browser.getControl("Start clearance now").click() |
---|
| 1219 | self.assertMatches('...Clearance process has been started...', |
---|
[16382] | 1220 | self.browser.contents) |
---|
| 1221 | |
---|
[16385] | 1222 | def test_student_medical_questionnaire(self): |
---|
[16386] | 1223 | self.app['configuration']['2004'].medical_quest_fee = 1000.0 |
---|
[16382] | 1224 | IWorkflowInfo(self.student).fireTransition('admit') |
---|
| 1225 | self.browser.open(self.login_path) |
---|
| 1226 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 1227 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 1228 | self.browser.getControl("Login").click() |
---|
| 1229 | self.assertMatches( |
---|
[17298] | 1230 | '...Did you know that with...', self.browser.contents) |
---|
[16382] | 1231 | self.browser.getLink("Base Data").click() |
---|
[16385] | 1232 | self.browser.getLink("Medical Questionnaire").click() |
---|
[16386] | 1233 | self.assertTrue('Please pay medical questionnaire payment first' in |
---|
| 1234 | self.browser.contents) |
---|
| 1235 | self.assertEqual(self.browser.url, self.student_path) |
---|
| 1236 | self.browser.open(self.payments_path) |
---|
| 1237 | self.browser.getLink("Add current session payment ticket").click() |
---|
| 1238 | self.browser.getControl(name="form.p_category").value = ['medical_quest'] |
---|
| 1239 | self.browser.getControl("Create ticket").click() |
---|
| 1240 | p_ticket = self.student['payments'].values()[0] |
---|
| 1241 | p_ticket.approveStudentPayment() |
---|
| 1242 | self.browser.getLink("Base Data").click() |
---|
| 1243 | self.browser.getLink("Medical Questionnaire").click() |
---|
[16385] | 1244 | self.browser.getLink("Download medical questionnaire slip").click() |
---|
[16382] | 1245 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 1246 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
[16385] | 1247 | path = os.path.join(samples_dir(), 'medical_questionnaire_slip.pdf') |
---|
[16382] | 1248 | open(path, 'wb').write(self.browser.contents) |
---|
[17255] | 1249 | print "Sample PDF medical_questionnaire_slip.pdf written to %s" % path |
---|
| 1250 | |
---|
| 1251 | self.browser.open(self.student_path) |
---|
| 1252 | self.browser.getLink("Medical Questionnaire").click() |
---|
| 1253 | self.browser.getControl(name="form.bloodgroup").value = 'A' |
---|
| 1254 | self.browser.getControl(name="form.genotype").value = 'XYZ' |
---|
| 1255 | self.browser.getControl("Save").click() |
---|
[17395] | 1256 | self.browser.getLink("Base Data").click() |
---|
[17255] | 1257 | self.browser.getLink("Download TISHIP registration slip").click() |
---|
| 1258 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 1259 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
| 1260 | path = os.path.join(samples_dir(), 'tiship_slip.pdf') |
---|
| 1261 | open(path, 'wb').write(self.browser.contents) |
---|
| 1262 | print "Sample PDF tiship_slip.pdf written to %s" % path |
---|
[17845] | 1263 | |
---|
| 1264 | def test_fiancial_clearance_pdf_slip(self): |
---|
| 1265 | payment1 = createObject(u'waeup.StudentOnlinePayment') |
---|
| 1266 | timestamp = ("%d" % int(time()*10000))[1:] |
---|
| 1267 | payment1.p_id = "LSCNEW-2-4153206270" # the longest possible p_id |
---|
| 1268 | payment1.p_category = 'schoolfee' |
---|
| 1269 | payment1.p_item = u'My School Fee' |
---|
| 1270 | payment1.p_session = 2015 |
---|
| 1271 | payment1.p_level = 100 |
---|
| 1272 | payment1.p_current = True |
---|
| 1273 | payment1.amount_auth = 23456.9 |
---|
| 1274 | payment1.approve() |
---|
| 1275 | payment2 = createObject(u'waeup.StudentOnlinePayment') |
---|
| 1276 | timestamp = ("%d" % int(time()*10000))[1:] |
---|
| 1277 | payment2.p_id = "p%s" % timestamp |
---|
| 1278 | payment2.p_category = 'clearance' |
---|
| 1279 | payment2.p_item = u'My Clearance Fee' |
---|
| 1280 | payment2.p_session = 2015 |
---|
| 1281 | payment2.p_level = 100 |
---|
| 1282 | payment2.p_current = True |
---|
| 1283 | payment2.amount_auth = 5678.6 |
---|
| 1284 | payment2.approve() |
---|
| 1285 | self.student['payments'][payment1.p_id] = payment1 |
---|
| 1286 | self.student['payments'][payment2.p_id] = payment2 |
---|
| 1287 | self.student.nysc = True |
---|
| 1288 | self.student.nysc_updated = datetime.now(pytz.utc) |
---|
| 1289 | self.student.nysc_senate_info = u'Senate Info test' |
---|
| 1290 | self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') |
---|
| 1291 | self.browser.open(self.student_path + '/clear_financially') |
---|
| 1292 | self.browser.getLink("Download fee payment history").click() |
---|
| 1293 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 1294 | self.assertEqual(self.browser.headers['Content-Type'], |
---|
| 1295 | 'application/pdf') |
---|
| 1296 | path = os.path.join(samples_dir(), 'fee_payment_history.pdf') |
---|
| 1297 | open(path, 'wb').write(self.browser.contents) |
---|
| 1298 | print "Sample PDF fee_payment_history.pdf written to %s" % path |
---|
| 1299 | return |
---|
[17885] | 1300 | |
---|
| 1301 | def test_affidavit_slip(self): |
---|
| 1302 | self.browser.open(self.login_path) |
---|
| 1303 | self.browser.getControl(name="form.login").value = self.student_id |
---|
| 1304 | self.browser.getControl(name="form.password").value = 'spwd' |
---|
| 1305 | self.browser.getControl("Login").click() |
---|
| 1306 | self.browser.getLink("Base Data").click() |
---|
| 1307 | self.browser.getLink("Upload affidavit of good conduct").click() |
---|
| 1308 | self.browser.getLink("Download affidavit of good conduct form").click() |
---|
| 1309 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 1310 | self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') |
---|
| 1311 | path = os.path.join(samples_dir(), 'affidavit_good_conduct.pdf') |
---|
| 1312 | open(path, 'wb').write(self.browser.contents) |
---|
| 1313 | print "Sample PDF affidavit_good_conduct.pdf written to %s" % path |
---|