[8926] | 1 | ## $Id: test_browser.py 17296 2023-01-16 20:41:05Z 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 | ## |
---|
| 18 | import os |
---|
| 19 | import shutil |
---|
| 20 | import tempfile |
---|
| 21 | import datetime |
---|
| 22 | import grok |
---|
| 23 | import pytz |
---|
| 24 | from zope.event import notify |
---|
| 25 | from zope.intid.interfaces import IIntIds |
---|
| 26 | from zope.interface.verify import verifyClass, verifyObject |
---|
| 27 | from zope.schema.interfaces import ConstraintNotSatisfied |
---|
| 28 | from zope.component.hooks import setSite, clearSite |
---|
| 29 | from zope.component import createObject, getUtility |
---|
| 30 | from zope.catalog.interfaces import ICatalog |
---|
| 31 | from zope.testbrowser.testing import Browser |
---|
| 32 | from hurry.workflow.interfaces import IWorkflowState |
---|
| 33 | from waeup.kofa.app import University |
---|
| 34 | from waeup.kofa.university.faculty import Faculty |
---|
| 35 | from waeup.kofa.university.department import Department |
---|
| 36 | from waeup.kofa.testing import FunctionalTestCase |
---|
| 37 | from waeup.kofa.configuration import SessionConfiguration |
---|
| 38 | from waeup.kofa.applicants.container import ApplicantsContainer |
---|
| 39 | from waeup.kofa.applicants.tests.test_batching import ApplicantImportExportSetup |
---|
[13163] | 40 | from waeup.kofa.interfaces import IBatchProcessor, IUserAccount |
---|
[8926] | 41 | from kofacustom.nigeria.testing import FunctionalLayer |
---|
[12080] | 42 | from kofacustom.nigeria.applicants.export import NigeriaApplicantExporter |
---|
[8926] | 43 | from kofacustom.nigeria.applicants.batching import NigeriaApplicantProcessor |
---|
| 44 | |
---|
[10899] | 45 | session_1 = datetime.datetime.now().year - 2 |
---|
| 46 | app_container_name = u'app%s' % session_1 |
---|
| 47 | pgft_container_name = u'pgft%s' % session_1 |
---|
[13163] | 48 | cbt_container_name = u'cbt%s' % session_1 |
---|
[8926] | 49 | |
---|
| 50 | class ApplicantUITest(FunctionalTestCase): |
---|
| 51 | """Perform some browser tests. |
---|
| 52 | """ |
---|
| 53 | layer = FunctionalLayer |
---|
| 54 | |
---|
| 55 | def setUp(self): |
---|
| 56 | super(ApplicantUITest, self).setUp() |
---|
| 57 | # Setup a sample site for each test |
---|
| 58 | app = University() |
---|
| 59 | self.dc_root = tempfile.mkdtemp() |
---|
| 60 | app['datacenter'].setStoragePath(self.dc_root) |
---|
| 61 | |
---|
| 62 | # Prepopulate the ZODB... |
---|
| 63 | self.getRootFolder()['app'] = app |
---|
| 64 | # we add the site immediately after creation to the |
---|
| 65 | # ZODB. Catalogs and other local utilities are not setup |
---|
| 66 | # before that step. |
---|
| 67 | self.app = self.getRootFolder()['app'] |
---|
| 68 | # Set site here. Some of the following setup code might need |
---|
| 69 | # to access grok.getSite() and should get our new app then |
---|
| 70 | setSite(app) |
---|
| 71 | |
---|
[13163] | 72 | # Add three different applicants containers |
---|
[8926] | 73 | self.pgcontainer = ApplicantsContainer() |
---|
[10899] | 74 | self.pgcontainer.code = pgft_container_name |
---|
[8926] | 75 | self.pgcontainer.prefix = u'pgft' |
---|
| 76 | self.pgcontainer.application_category = u'pg_ft' |
---|
[10899] | 77 | self.pgcontainer.year = session_1 |
---|
[8926] | 78 | self.pgcontainer.application_fee = 300.0 |
---|
[10899] | 79 | self.pgcontainer.title = u'This is the %s container' % pgft_container_name |
---|
| 80 | self.app['applicants'][pgft_container_name] = self.pgcontainer |
---|
[13163] | 81 | |
---|
[8926] | 82 | self.ugcontainer = ApplicantsContainer() |
---|
[10899] | 83 | self.ugcontainer.code = app_container_name |
---|
| 84 | self.ugcontainer.prefix = u'app' |
---|
[8926] | 85 | self.ugcontainer.application_category = u'basic' |
---|
[10899] | 86 | self.ugcontainer.year = session_1 |
---|
[8926] | 87 | self.ugcontainer.application_fee = 200.0 |
---|
[10899] | 88 | self.ugcontainer.title = u'This is the %s container' % app_container_name |
---|
| 89 | self.app['applicants'][app_container_name] = self.ugcontainer |
---|
[8926] | 90 | self.ugcontainer.mode = 'update' |
---|
| 91 | delta = datetime.timedelta(days=10) |
---|
| 92 | self.ugcontainer.startdate = datetime.datetime.now(pytz.utc) - delta |
---|
| 93 | self.ugcontainer.enddate = datetime.datetime.now(pytz.utc) + delta |
---|
| 94 | |
---|
[13163] | 95 | self.cbtcontainer = ApplicantsContainer() |
---|
| 96 | self.cbtcontainer.code = cbt_container_name |
---|
| 97 | self.cbtcontainer.prefix = u'cbt' |
---|
| 98 | self.cbtcontainer.application_category = u'basic' |
---|
| 99 | self.cbtcontainer.year = session_1 |
---|
| 100 | self.cbtcontainer.application_fee = 300.0 |
---|
| 101 | self.cbtcontainer.title = u'This is the %s container' % cbt_container_name |
---|
| 102 | self.app['applicants'][cbt_container_name] = self.cbtcontainer |
---|
| 103 | self.cbtcontainer.mode = 'update' |
---|
| 104 | delta = datetime.timedelta(days=10) |
---|
| 105 | self.cbtcontainer.startdate = datetime.datetime.now(pytz.utc) - delta |
---|
| 106 | self.cbtcontainer.enddate = datetime.datetime.now(pytz.utc) + delta |
---|
| 107 | |
---|
[8926] | 108 | # Populate university |
---|
| 109 | self.certificate = createObject('waeup.Certificate') |
---|
| 110 | self.certificate.code = 'CERT1' |
---|
| 111 | self.certificate.application_category = 'basic' |
---|
| 112 | self.certificate.start_level = 100 |
---|
| 113 | self.certificate.end_level = 500 |
---|
| 114 | self.certificate.study_mode = u'ug_ft' |
---|
| 115 | self.app['faculties']['fac1'] = Faculty() |
---|
| 116 | self.app['faculties']['fac1']['dep1'] = Department() |
---|
| 117 | self.app['faculties']['fac1']['dep1'].certificates.addCertificate( |
---|
| 118 | self.certificate) |
---|
| 119 | self.certificate2 = createObject('waeup.Certificate') |
---|
| 120 | self.certificate2.code = 'CERT2' |
---|
| 121 | self.certificate2.application_category = 'pg_ft' |
---|
| 122 | self.certificate2.start_level = 100 |
---|
| 123 | self.certificate2.end_level = 500 |
---|
| 124 | self.certificate.study_mode = u'pg_ft' |
---|
| 125 | self.app['faculties']['fac1']['dep1'].certificates.addCertificate( |
---|
| 126 | self.certificate2) |
---|
| 127 | |
---|
| 128 | # Add (customized) applicants |
---|
| 129 | pgapplicant = createObject(u'waeup.Applicant') |
---|
| 130 | pgapplicant.firstname = u'Anna' |
---|
| 131 | pgapplicant.lastname = u'Post' |
---|
[10899] | 132 | self.app['applicants'][pgft_container_name].addApplicant(pgapplicant) |
---|
[8926] | 133 | self.pgapplication_number = pgapplicant.application_number |
---|
[10899] | 134 | self.pgapplicant = self.app['applicants'][pgft_container_name][ |
---|
[8926] | 135 | self.pgapplication_number] |
---|
| 136 | |
---|
| 137 | ugapplicant = createObject(u'waeup.Applicant') |
---|
| 138 | ugapplicant.firstname = u'Klaus' |
---|
| 139 | ugapplicant.lastname = u'Under' |
---|
[10899] | 140 | self.app['applicants'][app_container_name].addApplicant(ugapplicant) |
---|
[8926] | 141 | self.ugapplication_number = ugapplicant.application_number |
---|
[10899] | 142 | self.ugapplicant = self.app['applicants'][app_container_name][ |
---|
[8926] | 143 | self.ugapplication_number] |
---|
[13163] | 144 | |
---|
| 145 | cbtapplicant = createObject(u'waeup.Applicant') |
---|
| 146 | cbtapplicant.firstname = u'Anna' |
---|
| 147 | cbtapplicant.lastname = u'Cbt' |
---|
| 148 | self.app['applicants'][cbt_container_name].addApplicant(cbtapplicant) |
---|
| 149 | self.cbtapplication_number = cbtapplicant.application_number |
---|
| 150 | self.cbtapplicant = self.app['applicants'][cbt_container_name][ |
---|
| 151 | self.cbtapplication_number] |
---|
| 152 | IUserAccount(self.cbtapplicant).setPassword('apwd') |
---|
| 153 | |
---|
| 154 | self.login_path = 'http://localhost/app/login' |
---|
| 155 | self.logout_path = 'http://localhost/app/logout' |
---|
[10899] | 156 | self.pgapplicant_path = ('http://localhost/app/applicants/%s/%s' |
---|
| 157 | % (pgft_container_name, self.pgapplication_number)) |
---|
| 158 | self.ugapplicant_path = ('http://localhost/app/applicants/%s/%s' |
---|
| 159 | % (app_container_name, self.ugapplication_number)) |
---|
[13163] | 160 | self.cbtapplicant_path = ('http://localhost/app/applicants/%s/%s' |
---|
| 161 | % (cbt_container_name, self.cbtapplication_number)) |
---|
[8926] | 162 | |
---|
| 163 | self.browser = Browser() |
---|
| 164 | self.browser.handleErrors = False |
---|
| 165 | |
---|
[10899] | 166 | configuration = SessionConfiguration() |
---|
| 167 | configuration.academic_session = session_1 |
---|
| 168 | configuration.application_fee = 200.0 |
---|
| 169 | self.app['configuration'].addSessionConfiguration(configuration) |
---|
| 170 | |
---|
[8926] | 171 | def tearDown(self): |
---|
| 172 | super(ApplicantUITest, self).tearDown() |
---|
| 173 | shutil.rmtree(self.dc_root) |
---|
| 174 | clearSite() |
---|
| 175 | return |
---|
| 176 | |
---|
| 177 | def fill_correct_values(self): |
---|
| 178 | self.browser.getControl(name="form.reg_number").value = '1234' |
---|
| 179 | self.browser.getControl(name="form.firstname").value = 'John' |
---|
| 180 | self.browser.getControl(name="form.lastname").value = 'Tester' |
---|
| 181 | self.browser.getControl(name="form.date_of_birth").value = '09/09/1988' |
---|
| 182 | self.browser.getControl(name="form.lga").value = ['foreigner'] |
---|
| 183 | self.browser.getControl(name="form.nationality").value = ['NG'] |
---|
| 184 | self.browser.getControl(name="form.sex").value = ['m'] |
---|
| 185 | self.browser.getControl(name="form.email").value = 'xx@yy.zz' |
---|
| 186 | |
---|
| 187 | def test_manage_and_view_applicant(self): |
---|
| 188 | # Managers can manage pg applicants. |
---|
| 189 | self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') |
---|
| 190 | # The IPGApplicant interface is really used in all pages. |
---|
| 191 | self.browser.open(self.pgapplicant_path) |
---|
| 192 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 193 | self.assertTrue('Employer' in self.browser.contents) |
---|
| 194 | self.browser.open(self.pgapplicant_path + '/manage') |
---|
| 195 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 196 | self.assertTrue('Employer' in self.browser.contents) |
---|
| 197 | self.browser.open(self.pgapplicant_path + '/edit') |
---|
| 198 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 199 | self.assertTrue('Employer' in self.browser.contents) |
---|
| 200 | self.browser.open(self.pgapplicant_path + '/application_slip.pdf') |
---|
| 201 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 202 | # If we view the applicant in the ug container, |
---|
| 203 | # the employer field doesn't appear. |
---|
| 204 | self.browser.open(self.ugapplicant_path) |
---|
| 205 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 206 | self.assertFalse('Employer' in self.browser.contents) |
---|
| 207 | self.browser.open(self.ugapplicant_path + '/manage') |
---|
| 208 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 209 | # We can save the applicant. |
---|
| 210 | self.fill_correct_values() |
---|
| 211 | self.browser.getControl(name="form.course1").value = ['CERT1'] |
---|
| 212 | self.browser.getControl("Save").click() |
---|
| 213 | self.assertMatches('...Form has been saved...', self.browser.contents) |
---|
| 214 | self.assertFalse('Employer' in self.browser.contents) |
---|
| 215 | self.browser.open(self.ugapplicant_path + '/edit') |
---|
| 216 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 217 | self.assertFalse('Employer' in self.browser.contents) |
---|
| 218 | self.browser.open(self.ugapplicant_path + '/application_slip.pdf') |
---|
| 219 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 220 | return |
---|
| 221 | |
---|
| 222 | def test_set_wrong_course1(self): |
---|
| 223 | self.ugapplicant.course1 = self.certificate |
---|
| 224 | self.assertRaises( |
---|
| 225 | ConstraintNotSatisfied, |
---|
| 226 | setattr, self.ugapplicant, 'course1', self.certificate2) |
---|
| 227 | self.pgapplicant.course1 = self.certificate2 |
---|
| 228 | self.assertRaises( |
---|
| 229 | ConstraintNotSatisfied, |
---|
| 230 | setattr, self.pgapplicant, 'course1', self.certificate) |
---|
| 231 | return |
---|
| 232 | |
---|
| 233 | def test_application_payment(self): |
---|
| 234 | self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') |
---|
| 235 | |
---|
| 236 | # UG (UTME) applicant |
---|
| 237 | self.browser.open(self.ugapplicant_path) |
---|
| 238 | self.browser.open(self.ugapplicant_path + '/manage') |
---|
| 239 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 240 | self.fill_correct_values() |
---|
| 241 | self.browser.getControl(name="form.course1").value = ['CERT1'] |
---|
| 242 | self.browser.getControl("Save").click() |
---|
| 243 | self.assertMatches('...Form has been saved...', self.browser.contents) |
---|
| 244 | self.browser.getControl("Add online payment ticket").click() |
---|
| 245 | self.assertMatches('...Payment ticket created...', |
---|
| 246 | self.browser.contents) |
---|
| 247 | self.assertMatches('...Amount Authorized...', |
---|
| 248 | self.browser.contents) |
---|
| 249 | payment_id = self.ugapplicant.keys()[0] |
---|
| 250 | payment = self.ugapplicant[payment_id] |
---|
[10899] | 251 | self.assertEqual(payment.p_item,'This is the %s container' % app_container_name) |
---|
| 252 | self.assertEqual(payment.p_session,session_1) |
---|
[8926] | 253 | self.assertEqual(payment.p_category,'application') |
---|
| 254 | self.assertEqual(payment.amount_auth, 200.0) |
---|
| 255 | |
---|
| 256 | # PG applicants pay more |
---|
| 257 | self.browser.open(self.pgapplicant_path) |
---|
| 258 | self.browser.open(self.pgapplicant_path + '/manage') |
---|
| 259 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 260 | self.fill_correct_values() |
---|
| 261 | self.browser.getControl(name="form.course1").value = ['CERT2'] |
---|
| 262 | self.browser.getControl(name="form.reg_number").value = '2345' |
---|
| 263 | self.browser.getControl(name="form.firstname").value = 'Anna' |
---|
| 264 | self.browser.getControl("Save").click() |
---|
| 265 | self.assertMatches('...Form has been saved...', self.browser.contents) |
---|
| 266 | self.browser.getControl("Add online payment ticket").click() |
---|
| 267 | self.assertMatches('...Payment ticket created...', |
---|
| 268 | self.browser.contents) |
---|
| 269 | self.assertMatches('...Amount Authorized...', |
---|
| 270 | self.browser.contents) |
---|
| 271 | payment_id = self.pgapplicant.keys()[0] |
---|
| 272 | payment = self.pgapplicant[payment_id] |
---|
[10899] | 273 | self.assertEqual(payment.p_item,'This is the %s container' % pgft_container_name) |
---|
| 274 | self.assertEqual(payment.p_session,session_1) |
---|
[8926] | 275 | self.assertEqual(payment.p_category,'application') |
---|
| 276 | self.assertEqual(payment.amount_auth, 300.0) |
---|
| 277 | return |
---|
| 278 | |
---|
[10379] | 279 | def test_hide_screening_data(self): |
---|
| 280 | self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') |
---|
| 281 | self.browser.open(self.ugapplicant_path + '/manage') |
---|
| 282 | self.assertEqual(self.browser.headers['Status'], '200 Ok') |
---|
| 283 | self.fill_correct_values() |
---|
| 284 | self.browser.getControl(name="form.screening_venue").value = 'Mensa' |
---|
| 285 | self.browser.getControl(name="form.screening_date").value = 'Easter' |
---|
| 286 | self.browser.getControl(name="form.course1").value = ['CERT1'] |
---|
| 287 | self.browser.getControl("Save").click() |
---|
| 288 | self.assertMatches('...Form has been saved...', self.browser.contents) |
---|
| 289 | self.browser.getControl("Save").click() |
---|
| 290 | # Venue and date are not shown |
---|
| 291 | self.browser.open(self.ugapplicant_path) |
---|
| 292 | self.assertFalse('Screening' in self.browser.contents) |
---|
| 293 | IWorkflowState(self.ugapplicant).setState('paid') |
---|
| 294 | # Venue and date are shown if applicant has paid |
---|
| 295 | self.browser.open(self.ugapplicant_path) |
---|
| 296 | self.assertTrue('Screening' in self.browser.contents) |
---|
| 297 | return |
---|
| 298 | |
---|
[8926] | 299 | def test_register_applicant_update(self): |
---|
| 300 | # An applicant can register himself. |
---|
| 301 | self.ugapplicant.reg_number = u'1234' |
---|
| 302 | notify(grok.ObjectModifiedEvent(self.ugapplicant)) |
---|
[10899] | 303 | self.browser.open('http://localhost/app/applicants/%s/' % app_container_name) |
---|
[8926] | 304 | self.browser.getLink("Register for application").click() |
---|
| 305 | # Fill the edit form with suitable values |
---|
[11739] | 306 | self.browser.getControl(name="form.lastname").value = 'Under' |
---|
[8926] | 307 | self.browser.getControl(name="form.email").value = 'xx@yy.zz' |
---|
| 308 | self.browser.getControl(name="form.reg_number").value = '1234' |
---|
[9179] | 309 | self.browser.getControl("Send login credentials").click() |
---|
[8926] | 310 | self.assertMatches('...Your registration was successful...', |
---|
| 311 | self.browser.contents) |
---|
| 312 | self.assertFalse('...<td>Password:</td>...' in self.browser.contents) |
---|
| 313 | # The new applicant can be found in the catalog via the email address |
---|
| 314 | cat = getUtility(ICatalog, name='applicants_catalog') |
---|
| 315 | results = list( |
---|
| 316 | cat.searchResults(email=('xx@yy.zz', 'xx@yy.zz'))) |
---|
| 317 | applicant = results[0] |
---|
| 318 | self.assertEqual(applicant.lastname,'Under') |
---|
| 319 | # The applicant can be found in the catalog via the reg_number |
---|
| 320 | results = list( |
---|
| 321 | cat.searchResults( |
---|
| 322 | reg_number=(applicant.reg_number, applicant.reg_number))) |
---|
| 323 | self.assertEqual(applicant,results[0]) |
---|
| 324 | return |
---|
| 325 | |
---|
| 326 | def test_create_ugstudent(self): |
---|
| 327 | self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') |
---|
| 328 | manage_path = 'http://localhost/app/applicants/%s/%s/%s' % ( |
---|
[10899] | 329 | app_container_name, self.ugapplicant.application_number, 'manage') |
---|
[8926] | 330 | self.browser.open(manage_path) |
---|
| 331 | self.fill_correct_values() |
---|
| 332 | self.browser.getControl("Save").click() |
---|
| 333 | IWorkflowState(self.ugapplicant).setState('admitted') |
---|
| 334 | self.browser.getControl(name="form.course1").value = ['CERT1'] |
---|
| 335 | self.browser.getControl(name="form.course_admitted").value = ['CERT1'] |
---|
| 336 | self.browser.getControl("Save").click() |
---|
| 337 | self.browser.getLink("Create student").click() |
---|
| 338 | student_id = self.app['students'].keys()[0] |
---|
| 339 | self.assertTrue(('Student %s created' % student_id) |
---|
| 340 | in self.browser.contents) |
---|
| 341 | student = self.app['students'][student_id] |
---|
| 342 | self.assertEqual(student.email, 'xx@yy.zz') |
---|
| 343 | self.assertEqual(student.firstname, 'John') |
---|
| 344 | self.assertEqual(student.lastname, 'Tester') |
---|
| 345 | # Also additional attributes have been copied. |
---|
| 346 | self.assertEqual(student.lga, 'foreigner') |
---|
| 347 | self.assertEqual(student.nationality, 'NG') |
---|
| 348 | return |
---|
| 349 | |
---|
[13163] | 350 | def test_applicant_access(self): |
---|
| 351 | # Applicants can edit their record |
---|
| 352 | self.browser.open(self.login_path) |
---|
| 353 | self.browser.getControl( |
---|
| 354 | name="form.login").value = self.cbtapplicant.applicant_id |
---|
| 355 | self.browser.getControl(name="form.password").value = 'apwd' |
---|
| 356 | self.browser.getControl("Login").click() |
---|
| 357 | self.assertTrue( |
---|
[17296] | 358 | 'You logged in as an applicant.' in self.browser.contents) |
---|
[13163] | 359 | self.browser.getLink("Edit application record").click() |
---|
| 360 | self.browser.getControl(name="form.date_of_birth").value = '09/09/1988' |
---|
| 361 | self.browser.getControl(name="form.lga").value = ['foreigner'] |
---|
| 362 | self.browser.getControl(name="form.nationality").value = ['NG'] |
---|
| 363 | self.browser.getControl(name="form.sex").value = ['m'] |
---|
| 364 | self.browser.getControl(name="form.email").value = 'xx@yy.zz' |
---|
| 365 | self.browser.getControl(name="form.course1").value = ['CERT1'] |
---|
| 366 | self.browser.getControl("Save").click() |
---|
| 367 | self.assertMatches('...Form has been saved...', self.browser.contents) |
---|
| 368 | |
---|
[12080] | 369 | class ApplicantExporterTest(ApplicantImportExportSetup): |
---|
[8926] | 370 | |
---|
| 371 | layer = FunctionalLayer |
---|
| 372 | |
---|
| 373 | def setUp(self): |
---|
[12080] | 374 | super(ApplicantExporterTest, self).setUp() |
---|
[8926] | 375 | self.outfile = os.path.join(self.workdir, 'myoutput.csv') |
---|
| 376 | self.cat = getUtility(ICatalog, name='applicants_catalog') |
---|
| 377 | self.intids = getUtility(IIntIds) |
---|
| 378 | return |
---|
| 379 | |
---|
| 380 | def setup_applicant(self, applicant): |
---|
| 381 | # set predictable values for `applicant` |
---|
| 382 | applicant.reg_number = u'123456' |
---|
| 383 | applicant.applicant_id = u'dp2011_654321' |
---|
| 384 | applicant.firstname = u'Anna' |
---|
| 385 | applicant.lastname = u'Tester' |
---|
| 386 | applicant.middlename = u'M.' |
---|
[9449] | 387 | applicant.nationality = u'NG' |
---|
[8926] | 388 | applicant.date_of_birth = datetime.date(1981, 2, 4) |
---|
| 389 | applicant.sex = 'f' |
---|
| 390 | applicant.email = 'anna@sample.com' |
---|
| 391 | applicant.phone = u'+234-123-12345' |
---|
| 392 | applicant.course1 = self.certificate |
---|
| 393 | applicant.course2 = self.certificate |
---|
| 394 | applicant.course_admitted = self.certificate |
---|
| 395 | applicant.notice = u'Some notice\nin lines.' |
---|
[13155] | 396 | applicant.jamb_subjects = u'Line 1\nLine 2' |
---|
[13160] | 397 | applicant.jamb_subjects_list = ['english_language', 'fine_art'] |
---|
[8926] | 398 | applicant.screening_score = 98 |
---|
| 399 | applicant.screening_venue = u'Exam Room' |
---|
| 400 | applicant.screening_date = u'Saturday, 16th June 2012 2:00:00 PM' |
---|
| 401 | applicant.password = 'any password' |
---|
| 402 | return applicant |
---|
| 403 | |
---|
| 404 | def test_export_reimport_all(self): |
---|
| 405 | # we can export all applicants in a portal |
---|
| 406 | # set values we can expect in export file |
---|
| 407 | self.applicant = self.setup_applicant(self.applicant) |
---|
[12080] | 408 | exporter = NigeriaApplicantExporter() |
---|
[8926] | 409 | exporter.export_all(self.app, self.outfile) |
---|
| 410 | result = open(self.outfile, 'rb').read() |
---|
[9449] | 411 | self.assertMatches(result, |
---|
[14093] | 412 | 'aggregate,applicant_id,bank_account_name,bank_account_number,' |
---|
[15489] | 413 | 'bank_name,course1,course2,course_admitted,date_of_birth,' |
---|
| 414 | 'disabilities,email,' |
---|
[14093] | 415 | 'emp2_end,emp2_position,emp2_reason,emp2_start,emp_end,' |
---|
| 416 | 'emp_position,emp_reason,emp_start,employer,employer2,' |
---|
| 417 | 'firstname,fst_sit_date,fst_sit_fname,fst_sit_no,' |
---|
| 418 | 'fst_sit_results,fst_sit_type,hq_degree,hq_disc,' |
---|
| 419 | 'hq_fname,hq_matric_no,hq_school,hq_session,hq_type,' |
---|
| 420 | 'jamb_reg_number,jamb_score,jamb_subjects,jamb_subjects_list,' |
---|
| 421 | 'lastname,lga,locked,middlename,nationality,notice,nysc_lga,' |
---|
| 422 | 'nysc_year,phone,presently_inst,programme_type,reg_number,' |
---|
| 423 | 'result_uploaded,scd_sit_date,scd_sit_fname,scd_sit_no,' |
---|
| 424 | 'scd_sit_results,scd_sit_type,screening_date,screening_score,' |
---|
| 425 | 'screening_venue,sex,special_application,student_id,' |
---|
| 426 | 'suspended,password,state,history,container_code,' |
---|
| 427 | 'application_number,display_fullname,application_date\r\n' |
---|
[13142] | 428 | |
---|
[15489] | 429 | ',dp2011_654321,,,,CERT1,CERT1,CERT1,1981-02-04#,,' |
---|
[14093] | 430 | 'anna@sample.com,,,,,,,,,,,Anna,,,,,,,,,,,,,,,Line 1++Line 2,' |
---|
| 431 | '"[\'english_language\', \'fine_art\']",' |
---|
| 432 | 'Tester,,0,M.,NG,"Some notice\nin lines.",,,+234-123-12345#,,,' |
---|
| 433 | '123456,,,,,,,"Saturday, 16th June 2012 2:00:00 PM",98,' |
---|
| 434 | 'Exam Room,f,,,0,any password,initialized,' |
---|
| 435 | '[u\'2016-08-19 07:30:05 WAT - Application initialized by system\'],' |
---|
[13979] | 436 | 'dp2011,654321,Anna M. Tester,\r\n') |
---|
[8926] | 437 | # We can import the same file if we ignore some columns. |
---|
| 438 | # Since the applicants_catalog hasn't been notified, the same |
---|
| 439 | # record with same reg_number can be imported twice. |
---|
| 440 | processor = NigeriaApplicantProcessor() |
---|
| 441 | result = processor.doImport( |
---|
| 442 | self.outfile, |
---|
[13979] | 443 | [ |
---|
[14093] | 444 | 'aggregate','ignore_applicant_id','bank_account_name','bank_account_number', |
---|
[15489] | 445 | 'bank_name','course1','course2','course_admitted','date_of_birth', |
---|
| 446 | 'disabilities','email', |
---|
[14093] | 447 | 'emp2_end','emp2_position','emp2_reason','emp2_start','emp_end', |
---|
| 448 | 'emp_position','emp_reason','emp_start','employer','employer2', |
---|
| 449 | 'firstname','fst_sit_date','fst_sit_fname','fst_sit_no', |
---|
| 450 | 'fst_sit_results','fst_sit_type','hq_degree','hq_disc', |
---|
| 451 | 'hq_fname','hq_matric_no','hq_school','hq_session','hq_type', |
---|
| 452 | 'jamb_reg_number','jamb_score','jamb_subjects','jamb_subjects_list', |
---|
| 453 | 'lastname','lga','locked','middlename','nationality','notice','nysc_lga', |
---|
| 454 | 'nysc_year','phone','presently_inst','programme_type','reg_number', |
---|
| 455 | 'result_uploaded','scd_sit_date','scd_sit_fname','scd_sit_no', |
---|
| 456 | 'scd_sit_results','scd_sit_type','screening_date','screening_score', |
---|
| 457 | 'screening_venue','sex','special_application','student_id', |
---|
| 458 | 'suspended','password','state','history','container_code', |
---|
| 459 | 'application_number','display_fullname','application_date' |
---|
[13979] | 460 | ], |
---|
[8926] | 461 | mode='create') |
---|
| 462 | num_succ, num_fail, finished_path, failed_path = result |
---|
[9449] | 463 | #content = open(failed_path).read() |
---|
[8926] | 464 | self.assertEqual(num_succ,1) |
---|
| 465 | self.assertEqual(num_fail,0) |
---|
| 466 | # Now we ignore also the container_code and import the same file |
---|
| 467 | # in update mode which means that INigeriaApplicantUpdateByRegNo |
---|
| 468 | # is used for field conversion. applicant_id must be ignored |
---|
| 469 | # too since the previous import has notified the applicants_catalog |
---|
| 470 | # so that the portal 'knows' that reg_number is in use. |
---|
| 471 | processor = NigeriaApplicantProcessor() |
---|
| 472 | result = processor.doImport( |
---|
| 473 | self.outfile, |
---|
[13979] | 474 | [ |
---|
[14093] | 475 | 'aggregate','ignore_applicant_id','bank_account_name','bank_account_number', |
---|
[15489] | 476 | 'bank_name','course1','course2','course_admitted','date_of_birth', |
---|
| 477 | 'disabilities', 'email', |
---|
[14093] | 478 | 'emp2_end','emp2_position','emp2_reason','emp2_start','emp_end', |
---|
| 479 | 'emp_position','emp_reason','emp_start','employer','employer2', |
---|
| 480 | 'firstname','fst_sit_date','fst_sit_fname','fst_sit_no', |
---|
| 481 | 'fst_sit_results','fst_sit_type','hq_degree','hq_disc', |
---|
| 482 | 'hq_fname','hq_matric_no','hq_school','hq_session','hq_type', |
---|
| 483 | 'jamb_reg_number','jamb_score','jamb_subjects','jamb_subjects_list', |
---|
| 484 | 'lastname','lga','locked','middlename','nationality','notice','nysc_lga', |
---|
| 485 | 'nysc_year','phone','presently_inst','programme_type','reg_number', |
---|
| 486 | 'result_uploaded','scd_sit_date','scd_sit_fname','scd_sit_no', |
---|
| 487 | 'scd_sit_results','scd_sit_type','screening_date','screening_score', |
---|
| 488 | 'screening_venue','sex','special_application','student_id', |
---|
| 489 | 'suspended','password','state','ignore_history','ignore_container_code', |
---|
| 490 | 'ignore_application_number','display_fullname','application_date' |
---|
[13979] | 491 | ], |
---|
[8926] | 492 | mode='update') |
---|
| 493 | num_succ, num_fail, finished_path, failed_path = result |
---|
| 494 | self.assertEqual(num_succ,1) |
---|
| 495 | self.assertEqual(num_fail,0) |
---|
| 496 | return |
---|