source: main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_applicantcopier.py @ 16228

Last change on this file since 16228 was 16228, checked in by Henrik Bettermann, 4 years ago

Use Applicant.createStudent method also to create graduated
students from transcript application data (not used in base package).

  • Property svn:keywords set to Id
File size: 20.2 KB
Line 
1## $Id: test_applicantcopier.py 16228 2020-09-07 12:28:14Z 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"""
19Tests for the creation of student containers with data from admitted applicants.
20"""
21import os
22import grok
23from StringIO import StringIO
24from datetime import datetime
25from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
26from zope.event import notify
27from zope.component import getUtility
28from zope.i18n import translate
29from zope.securitypolicy.interfaces import IPrincipalRoleManager
30from waeup.kofa.testing import FunctionalLayer
31from waeup.kofa.interfaces import IExtFileStore, IFileStoreNameChooser
32from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
33from waeup.kofa.browser.tests.test_pdf import samples_dir
34
35session = datetime.now().year - 2
36
37class ApplicantCopierFunctionalTests(ApplicantsFullSetup):
38
39    layer = FunctionalLayer
40
41    def setUp(self):
42        super(ApplicantCopierFunctionalTests, self).setUp()
43        return
44
45    def prepare_applicant(self):
46        self.browser.open(self.manage_path)
47        self.fill_correct_values()
48        self.browser.getControl("Save").click()
49        # Upload a passport picture
50        ctrl = self.browser.getControl(name='form.passport')
51        file_obj = open(
52            os.path.join(os.path.dirname(__file__), 'test_image.jpg'),'rb')
53        file_ctrl = ctrl.mech_control
54        file_ctrl.add_file(file_obj, filename='my_photo.jpg')
55        self.browser.getControl("Save").click() # submit form
56        return
57
58    def test_applicant_student_copier(self):
59        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
60        self.prepare_applicant()
61        storage = getUtility(IExtFileStore)
62        # The stored image can be fetched
63        file_id = IFileStoreNameChooser(self.applicant).chooseName()
64        fd = storage.getFile(file_id)
65        file_len_orig = len(fd.read())
66        # We store a test pdf file
67        dummy_file = StringIO('test file')
68        testfile_id = IFileStoreNameChooser(
69            self.applicant).chooseName(attr='testfile.pdf')
70        test_file = storage.createFile(testfile_id, dummy_file)
71        # The stored file can be fetched
72        fd = storage.getFile(testfile_id)
73        testfile_len_orig = len(fd.read())
74        self.assertEqual(self.app['students']._curr_stud_id, 1000000)
75        # Let's try to create the student
76        (success, msg) = self.applicant.createStudent()
77        self.assertTrue(msg == 'Applicant has not yet been admitted.')
78        IWorkflowState(self.applicant).setState('admitted')
79        (success, msg) = self.applicant.createStudent()
80        # Current student_id has not changed.
81        self.assertEqual(self.app['students']._curr_stud_id, 1000000)
82        self.assertTrue(msg == 'No study course provided.')
83        self.browser.open(self.manage_path)
84        self.browser.getControl(name="form.course_admitted").value = ['CERT1']
85        self.browser.getControl("Save").click()
86        # Maybe the certificate has meanwhile been removed
87        del self.app['faculties']['fac1']['dep1'].certificates['CERT1']
88        (success, msg) = self.applicant.createStudent()
89        self.assertFalse(success)
90        self.assertTrue('ConstraintNotSatisfied: CERT1' in msg)
91        # Current student_id has not changed.
92        self.assertEqual(self.app['students']._curr_stud_id, 1000000)
93        # Ok, lets add the certificate and try again
94        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
95            self.certificate)
96        # Managers are not allowed to trigger the create transition manually
97        self.assertFalse('<option value="create">' in self.browser.contents)
98        # Student can be created
99        (success, msg) = self.applicant.createStudent()
100        self.assertTrue('created' in msg)
101        # Current student_id has not changed.
102        self.assertEqual(self.app['students']._curr_stud_id, 1000001)
103        # The applicant is locked
104        self.assertTrue(self.applicant.locked)
105        student_id = translate(msg, 'waeup.kofa').split()[1]
106        # View student container just created
107        student = self.app['students'][student_id]
108        student_path = 'http://localhost/app/students/%s' % student_id
109        self.browser.open(student_path)
110        self.assertEqual(self.browser.headers['Status'], '200 Ok')
111        self.assertEqual(self.browser.url, student_path)
112        # Student is in state admitted
113        self.assertEqual(student.state, 'admitted')
114        # Attributes properly set?
115        self.assertEqual(student.email, 'xx@yy.zz')
116        self.assertEqual(student.firstname, 'John')
117        self.assertEqual(student.middlename, 'Anthony')
118        self.assertEqual(student.lastname, 'Tester')
119        # student_id set in application record?
120        self.assertEqual(self.applicant.student_id, student.student_id)
121        # Check if passport image has been copied
122        file_id = IFileStoreNameChooser(student).chooseName(attr='passport.jpg')
123        fd = storage.getFile(file_id)
124        file_len = len(fd.read())
125        self.assertEqual(file_len_orig, file_len)
126        # Check if test file has been copied too (new)
127        file_id = IFileStoreNameChooser(student).chooseName(attr='testfile.jpg')
128        fd = storage.getFile(file_id)
129        file_len = len(fd.read())
130        self.assertEqual(testfile_len_orig, file_len)
131        # Check if application slip exists and is a PDF file
132        file_id = IFileStoreNameChooser(
133            student).chooseName(attr='application_slip.pdf')
134        pdf = storage.getFile(file_id).read()
135        self.assertTrue(len(pdf) > 0)
136        self.assertEqual(pdf[:8], '%PDF-1.4')
137        path = os.path.join(samples_dir(), 'application_slip.pdf')
138        open(path, 'wb').write(pdf)
139        print "Sample PDF application_slip.pdf written to %s" % path
140        # Check if there is an application slip link in UI
141        self.assertTrue('Application Slip' in self.browser.contents)
142        self.browser.getLink("Application Slip").click()
143        self.assertEqual(self.browser.headers['Status'], '200 Ok')
144        self.assertEqual(self.browser.headers['Content-Type'],
145                         'application/pdf')
146        # Has the student been properly indexed?
147        # Yes, we can find the student in department
148        self.browser.open('http://localhost/app/students')
149        self.browser.getControl(name="searchtype").value = ['depcode']
150        self.browser.getControl(name="searchterm").value = 'dep1'
151        self.browser.getControl("Find student(s)").click()
152        self.assertMatches('...John Anthony Tester...', self.browser.contents)
153        # Has the student studycourse the correct attributes?
154        self.assertEqual(student['studycourse'].certificate.code, 'CERT1')
155        self.assertEqual(student['studycourse'].entry_session, session)
156        self.assertEqual(student['studycourse'].entry_mode, 'ug_ft')
157        self.assertEqual(student['studycourse'].current_session, session)
158        self.assertEqual(student['studycourse'].current_level, 100)
159
160    def test_applicant_graduated_copier(self):
161        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
162        self.prepare_applicant()
163        storage = getUtility(IExtFileStore)
164        # The stored image can be fetched
165        file_id = IFileStoreNameChooser(self.applicant).chooseName()
166        fd = storage.getFile(file_id)
167        file_len_orig = len(fd.read())
168        # We store a test pdf file
169        dummy_file = StringIO('test file')
170        testfile_id = IFileStoreNameChooser(
171            self.applicant).chooseName(attr='testfile.pdf')
172        test_file = storage.createFile(testfile_id, dummy_file)
173        # The stored file can be fetched
174        fd = storage.getFile(testfile_id)
175        testfile_len_orig = len(fd.read())
176        self.assertEqual(self.app['students']._curr_stud_id, 1000000)
177        # Let's try to create the student
178        (success, msg) = self.applicant.createStudent(graduated=True)
179        self.assertTrue(msg == 'Applicant has not yet been processed.')
180        IWorkflowState(self.applicant).setState('processed')
181        (success, msg) = self.applicant.createStudent(graduated=True)
182        # Current student_id has not changed.
183        self.assertEqual(self.app['students']._curr_stud_id, 1000000)
184        self.assertTrue(msg == 'No study course provided.')
185        # The course_studied field is not used in the base package. Thus we
186        # have to set the attribute manually.
187        self.applicant.course_studied = self.certificate
188        self.browser.open(self.manage_path)
189        self.browser.getControl("Save").click()
190        # Maybe the certificate has meanwhile been removed
191        del self.app['faculties']['fac1']['dep1'].certificates['CERT1']
192        (success, msg) = self.applicant.createStudent(graduated=True)
193        self.assertFalse(success)
194        self.assertTrue('ConstraintNotSatisfied: CERT1' in msg)
195        # Current student_id has not changed.
196        self.assertEqual(self.app['students']._curr_stud_id, 1000000)
197        # Ok, lets add the certificate and try again
198        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
199            self.certificate)
200        # Managers are not allowed to trigger the create transition manually
201        self.assertFalse('<option value="create">' in self.browser.contents)
202        # Graduated student can be created
203        (success, msg) = self.applicant.createStudent(graduated=True)
204        self.assertTrue('created' in msg)
205        # Current student_id has not changed.
206        self.assertEqual(self.app['students']._curr_stud_id, 1000001)
207        student_id = translate(msg, 'waeup.kofa').split()[1]
208        # View student container just created
209        student = self.app['students'][student_id]
210        student_path = 'http://localhost/app/students/%s' % student_id
211        self.browser.open(student_path)
212        self.assertEqual(self.browser.headers['Status'], '200 Ok')
213        self.assertEqual(self.browser.url, student_path)
214        # Student is in state graduated
215        self.assertEqual(student.state, 'graduated')
216        # Attributes properly set?
217        self.assertEqual(student.email, 'xx@yy.zz')
218        self.assertEqual(student.firstname, 'John')
219        self.assertEqual(student.middlename, 'Anthony')
220        self.assertEqual(student.lastname, 'Tester')
221        # student_id set in application record?
222        self.assertEqual(self.applicant.student_id, student.student_id)
223        # Check if passport image has been copied
224        file_id = IFileStoreNameChooser(student).chooseName(attr='passport.jpg')
225        fd = storage.getFile(file_id)
226        file_len = len(fd.read())
227        self.assertEqual(file_len_orig, file_len)
228        # Check if test file has been copied too (new)
229        file_id = IFileStoreNameChooser(student).chooseName(attr='testfile.jpg')
230        fd = storage.getFile(file_id)
231        file_len = len(fd.read())
232        self.assertEqual(testfile_len_orig, file_len)
233        # Check if application slip exists and is a PDF file
234        file_id = IFileStoreNameChooser(
235            student).chooseName(attr='application_slip.pdf')
236        pdf = storage.getFile(file_id).read()
237        self.assertTrue(len(pdf) > 0)
238        self.assertEqual(pdf[:8], '%PDF-1.4')
239        path = os.path.join(samples_dir(), 'application_slip.pdf')
240        open(path, 'wb').write(pdf)
241        print "Sample PDF application_slip.pdf written to %s" % path
242        # Check if there is an application slip link in UI
243        self.assertTrue('Application Slip' in self.browser.contents)
244        self.browser.getLink("Application Slip").click()
245        self.assertEqual(self.browser.headers['Status'], '200 Ok')
246        self.assertEqual(self.browser.headers['Content-Type'],
247                         'application/pdf')
248        # Has the student been properly indexed?
249        # Yes, we can find the student in department
250        self.browser.open('http://localhost/app/students')
251        self.browser.getControl(name="searchtype").value = ['depcode']
252        self.browser.getControl(name="searchterm").value = 'dep1'
253        self.browser.getControl("Find student(s)").click()
254        self.assertMatches('...John Anthony Tester...', self.browser.contents)
255        # Has the student studycourse the correct attributes?
256        self.assertEqual(student['studycourse'].certificate.code, 'CERT1')
257        self.assertEqual(student['studycourse'].entry_session, session)
258        self.assertEqual(student['studycourse'].entry_mode, 'ug_ft')
259        self.assertEqual(student['studycourse'].current_session, session)
260        self.assertEqual(student['studycourse'].current_level, 100)
261
262    def test_batch_copying(self):
263        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
264        self.prepare_applicant()
265        IWorkflowState(self.applicant).setState('admitted')
266        self.browser.getControl(name="form.course_admitted").value = ['CERT1']
267        self.browser.getControl("Save").click()
268        self.browser.open(self.manage_container_path)
269        self.browser.getControl("Create students from selected", index=0).click()
270        self.assertTrue('No applicant selected' in self.browser.contents)
271        ctrl = self.browser.getControl(name='val_id')
272        ctrl.getControl(value=self.applicant.application_number).selected = True
273        self.browser.getControl("Create students from selected", index=0).click()
274        self.assertTrue('1 students successfully created' in self.browser.contents)
275
276    def test_hidden_batch_copying_container(self):
277        logfile = os.path.join(
278            self.app['datacenter'].storage, 'logs', 'applicants.log')
279        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
280        self.prepare_applicant()
281        self.browser.open(self.container_path + '/createallstudents')
282        self.assertTrue('No record found' in self.browser.contents)
283        self.assertFalse('Failed records' in self.browser.contents)
284        self.assertFalse('Successfully created records' in self.browser.contents)
285        IWorkflowState(self.applicant).setState('admitted')
286        notify(grok.ObjectModifiedEvent(self.applicant))
287        self.browser.open(self.container_path + '/createallstudents')
288        self.assertTrue('No study course provided' in self.browser.contents)
289        self.assertFalse('Successfully created records' in self.browser.contents)
290        self.assertTrue('Failed records' in self.browser.contents)
291        self.browser.open(self.manage_path)
292        self.browser.getControl(name="form.course_admitted").value = ['CERT1']
293        self.browser.getControl("Save").click()
294        # date_of_birth is not required for applicants but for students
295        self.applicant.date_of_birth = None
296        self.browser.open(self.container_path + '/createallstudents')
297        self.assertTrue('RequiredMissing: date_of_birth' in self.browser.contents)
298        self.assertTrue('Failed records' in self.browser.contents)
299        self.assertFalse('Successfully created records' in self.browser.contents)
300        self.browser.open(self.manage_path)
301        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
302        self.browser.getControl("Save").click()
303        self.browser.open(self.container_path + '/createallstudents')
304        self.assertFalse('Failed records' in self.browser.contents)
305        self.assertTrue('Successfully created records' in self.browser.contents)
306
307    def test_hidden_batch_copying_all(self):
308        logfile = os.path.join(
309            self.app['datacenter'].storage, 'logs', 'applicants.log')
310        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
311        self.prepare_applicant()
312        self.browser.open(self.manage_path)
313        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
314        #self.browser.getControl(name="form.course_admitted").value = ['CERT1']
315        self.browser.getControl("Save").click()
316        IWorkflowState(self.applicant).setState('admitted')
317        notify(grok.ObjectModifiedEvent(self.applicant))
318        self.browser.open(self.root_path + '/createallstudents')
319        self.assertTrue('No study course provided' in self.browser.contents)
320        self.applicant.course_admitted = self.certificate
321        self.browser.open(self.root_path + '/createallstudents')
322        self.assertTrue('Successfully created records:' in self.browser.contents)
323
324    def test_copier_wo_passport(self):
325        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
326        self.browser.open(self.manage_path)
327        self.fill_correct_values()
328        # Let's try to create the student
329        IWorkflowState(self.applicant).setState('admitted')
330        self.browser.getControl(name="form.course_admitted").value = ['CERT1']
331        self.browser.getControl("Save").click()
332        (success, msg) = self.applicant.createStudent()
333        self.assertTrue('created' in msg)
334
335    def test_copier_with_defective_passport_image(self):
336        IWorkflowState(self.applicant).setState('admitted')
337        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
338        self.browser.open(self.manage_path)
339        self.fill_correct_values()
340        self.browser.getControl("Save").click()
341        # Upload a passport picture
342        ctrl = self.browser.getControl(name='form.passport')
343        # This file has really been uploaded by KwaraPoly student
344        # Until 4/1/15 these files resulted a traceback when opening
345        # the createallstudents page. The traceback is now catched.
346        file_obj = open(
347            os.path.join(os.path.dirname(__file__), 'fake_image.jpg'),'rb')
348        file_ctrl = ctrl.mech_control
349        file_ctrl.add_file(file_obj, filename='my_photo.jpg')
350        self.browser.getControl(name="form.course_admitted").value = ['CERT1']
351        self.browser.getControl("Save").click() # submit form
352        (success, msg) = self.applicant.createStudent()
353        self.assertTrue(msg == 'IOError: Application Slip could not be created.')
354        # The same in the UI
355        self.browser.open(self.manage_container_path)
356        ctrl = self.browser.getControl(name='val_id')
357        ctrl.getControl(value=self.applicant.application_number).selected = True
358        self.browser.getControl("Create students from selected", index=0).click()
359        self.assertTrue('No student could be created.' in self.browser.contents)
360        self.browser.open(self.container_path + '/createallstudents')
361        self.assertTrue(
362            'IOError: Application Slip could not be created.'
363            in self.browser.contents)
364
365    def disabled_test_delay(self):
366        # Create portalmanager manager
367        self.app['users'].addUser('mrportalmanager', 'mrportalmanagersecret')
368        self.app['users']['mrportalmanager'].email = 'mrportalmanager@foo.ng'
369        self.app['users']['mrportalmanager'].title = 'Carlos Portales'
370        prmglobal = IPrincipalRoleManager(self.app)
371        prmglobal.assignRoleToPrincipal(
372            'waeup.PortalManager', 'mrportalmanager')
373        # Login as portal manager
374        self.browser.open(self.login_path)
375        self.browser.getControl(name="form.login").value = 'mrportalmanager'
376        self.browser.getControl(name="form.password").value = 'mrportalmanagersecret'
377        self.browser.getControl("Login").click()
378        self.prepare_applicant()
379        self.browser.open(self.manage_path)
380        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
381        self.browser.getControl(name="form.course_admitted").value = ['CERT1']
382        self.browser.getControl("Save").click()
383        IWorkflowState(self.applicant).setState('admitted')
384        notify(grok.ObjectModifiedEvent(self.applicant))
385        start = datetime.now()
386        self.browser.open(self.root_path + '/createallstudents')
387        self.assertTrue('1 students successfully created' in self.browser.contents)
388        self.assertTrue((datetime.now() - start).seconds >= 10)
Note: See TracBrowser for help on using the repository browser.