## $Id: test_browser.py 17734 2024-04-04 12:19:05Z henrik $ ## ## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## import os import shutil import tempfile from StringIO import StringIO from hurry.workflow.interfaces import IWorkflowState, IWorkflowInfo from zope.component.hooks import setSite, clearSite from zope.component import getUtility, createObject from zope.interface import verify from waeup.kofa.app import University from waeup.kofa.students.tests.test_browser import ( StudentsFullSetup, SAMPLE_IMAGE) from waeup.kofa.students.accommodation import BedTicket from waeup.kofa.testing import FunctionalTestCase from waeup.kofa.browser.tests.test_pdf import samples_dir from waeup.kofa.interfaces import ( IExtFileStore, IFileStoreNameChooser) from waeup.kofa.students.interfaces import IStudentsUtils from waeup.fceokene.testing import FunctionalLayer class StudentProcessorTest(FunctionalTestCase): """Perform some batching tests. """ layer = FunctionalLayer def setUp(self): super(StudentProcessorTest, self).setUp() # Setup a sample site for each test app = University() self.dc_root = tempfile.mkdtemp() app['datacenter'].setStoragePath(self.dc_root) # Prepopulate the ZODB... self.getRootFolder()['app'] = app # we add the site immediately after creation to the # ZODB. Catalogs and other local utilities are not setup # before that step. self.app = self.getRootFolder()['app'] # Set site here. Some of the following setup code might need # to access grok.getSite() and should get our new app then setSite(app) def tearDown(self): super(StudentProcessorTest, self).tearDown() shutil.rmtree(self.workdir) shutil.rmtree(self.dc_root) clearSite() return class StudentUITests(StudentsFullSetup): """Tests for customized student class views and pages """ layer = FunctionalLayer def setUp(self): super(StudentUITests, self).setUp() bedticket = BedTicket() bedticket.booking_session = 2004 bedticket.bed_type = u'any bed type' bedticket.bed = self.app['hostels']['hall-1']['hall-1_A_101_A'] bedticket.bed_coordinates = u'My bed coordinates' self.student['accommodation'].addBedTicket(bedticket) def test_manage_payments(self): # Add missing configuration data self.app['configuration']['2004'].clearance_fee = 120.0 self.app['configuration']['2004'].booking_fee = 150.0 self.app['configuration']['2004'].maint_fee = 180.0 # Managers can add online payment tickets self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') self.browser.open(self.payments_path) self.browser.getLink("Add current session payment ticket").click() self.browser.getControl(name="form.p_category").value = ['schoolfee'] self.browser.getControl("Create ticket").click() self.assertMatches('...Wrong state...', self.browser.contents) IWorkflowState(self.student).setState('cleared') self.browser.open(self.payments_path + '/addop') self.browser.getControl(name="form.p_category").value = ['schoolfee'] self.browser.getControl("Create ticket").click() self.assertMatches('...ticket created...', self.browser.contents) self.browser.open(self.payments_path) ctrl = self.browser.getControl(name='val_id') value = ctrl.options[0] self.browser.getLink(value).click() self.assertMatches('...Amount Authorized...', self.browser.contents) # Managers can open payment slip because we did not proceed to # any payment gateway self.assertFalse('Download payment slip' in self.browser.contents) # Set ticket paid ticket = self.student['payments'].items()[0][1] ticket.p_state = 'paid' self.browser.open(self.payments_path + '/addop') self.browser.getControl(name="form.p_category").value = ['schoolfee'] self.browser.getControl("Create ticket").click() self.assertMatches('...This type of payment has already been made...', self.browser.contents) # Remove all payments so that we can add a school fee payment again keys = [i for i in self.student['payments'].keys()] for payment in keys: del self.student['payments'][payment] self.browser.open(self.payments_path + '/addop') self.browser.getControl(name="form.p_category").value = ['schoolfee'] self.browser.getControl("Create ticket").click() self.assertMatches('...ticket created...', self.browser.contents) #self.certificate.study_mode = 'nce_sw' #self.browser.open(self.payments_path + '/addop') #self.browser.getControl(name="form.p_category").value = ['third_semester'] #self.browser.getControl("Create ticket").click() #self.assertMatches('...could not be determined...', # self.browser.contents) #self.certificate.study_mode = 'nce_ft' #self.browser.open(self.payments_path + '/addop') #self.browser.getControl(name="form.p_category").value = ['third_semester'] #self.student['studycourse'].current_level = 300 #self.browser.getControl("Create ticket").click() #self.assertMatches('...Amount could not be determined...', self.browser.contents) self.browser.open(self.payments_path + '/addop') self.browser.getControl( name="form.p_category").value = ['bed_allocation'] self.browser.getControl("Create ticket").click() self.assertMatches('...ticket created...', self.browser.contents) self.browser.open(self.payments_path + '/addop') self.browser.getControl( name="form.p_category").value = ['hostel_maintenance'] self.browser.getControl("Create ticket").click() self.assertMatches('...ticket created...', self.browser.contents) self.browser.open(self.payments_path + '/addop') self.browser.getControl(name="form.p_category").value = ['clearance'] self.browser.getControl("Create ticket").click() self.assertMatches('...ticket created...', self.browser.contents) self.certificate.study_mode = 'pd_ft' self.browser.open(self.payments_path + '/addop') self.browser.getControl(name="form.p_category").value = ['schoolfee'] self.browser.getControl("Create ticket").click() self.assertMatches('...ticket created...', self.browser.contents) # In state returning we can add a new school fee ticket since # p_session and p_level is different IWorkflowState(self.student).setState('returning') self.browser.open(self.payments_path + '/addop') self.browser.getControl(name="form.p_category").value = ['schoolfee'] self.browser.getControl("Create ticket").click() # Uups, we forgot to add a session configuration for next session self.assertTrue('Session configuration object is not available.' in self.browser.contents) configuration = createObject('waeup.SessionConfiguration') configuration.academic_session = 2005 self.app['configuration'].addSessionConfiguration(configuration) self.browser.getControl(name="form.p_category").value = ['schoolfee'] self.browser.getControl("Create ticket").click() self.assertMatches('...ticket created...', self.browser.contents) # In state admitted school fee can't be determined IWorkflowState(self.student).setState('admitted') self.browser.open(self.payments_path + '/addop') self.browser.getControl(name="form.p_category").value = ['schoolfee'] self.browser.getControl("Create ticket").click() self.assertMatches('...Wrong state...', self.browser.contents) def test_student_payments(self): # Login IWorkflowState(self.student).setState('returning') self.browser.open(self.login_path) self.browser.getControl(name="form.login").value = self.student_id self.browser.getControl(name="form.password").value = 'spwd' self.browser.getControl("Login").click() self.browser.open(self.student_path + '/payments') self.assertTrue( 'Add current session payment ticket' in self.browser.contents) self.assertFalse( 'Add previous session payment ticket' in self.browser.contents) return def test_get_returning_data(self): # Student is in level 100, session 2004 with verdict A utils = getUtility(IStudentsUtils) self.assertEqual(utils.getReturningData(self.student),(2005, 200)) self.student['studycourse'].current_verdict = 'C' self.assertEqual(utils.getReturningData(self.student),(2005, 110)) self.student['studycourse'].current_verdict = 'D' self.assertEqual(utils.getReturningData(self.student),(2005, 100)) self.student['studycourse'].current_verdict = 'O' self.assertEqual(utils.getReturningData(self.student),(2004, 110)) return def test_set_payment_details(self): self.app['configuration']['2004'].booking_fee = 150.0 self.app['configuration']['2004'].maint_fee = 180.0 self.app['configuration']['2004'].clearance_fee = 120.0 utils = getUtility(IStudentsUtils) error, payment = utils.setPaymentDetails('schoolfee',self.student) self.assertEqual(payment, None) self.assertEqual(error, u'Wrong state.') IWorkflowState(self.student).setState('cleared') self.certificate.study_mode = 'pd_ft' error, payment = utils.setPaymentDetails('schoolfee',self.student) self.assertEqual(payment.p_level, 100) self.assertEqual(payment.p_session, 2004) self.assertEqual(payment.amount_auth, 70000) self.assertEqual(payment.p_item, u'CERT1') self.assertEqual(error, None) IWorkflowState(self.student).setState('returning') error, payment = utils.setPaymentDetails('schoolfee',self.student) self.assertEqual('Session configuration object is not available.', error) configuration = createObject('waeup.SessionConfiguration') configuration.academic_session = 2005 self.app['configuration'].addSessionConfiguration(configuration) error, payment = utils.setPaymentDetails('schoolfee',self.student) self.assertEqual(payment.p_level, 200) self.assertEqual(payment.p_session, 2005) self.assertEqual(payment.amount_auth, 35300) self.assertEqual(payment.p_item, u'CERT1') self.assertEqual(error, None) # UG returning students pay 70700 self.certificate.study_mode = 'ug_ft' error, payment = utils.setPaymentDetails('schoolfee',self.student) self.assertEqual(payment.amount_auth, 96700) self.assertEqual(error, None) # UG cleared students pay 87200 IWorkflowState(self.student).setState('cleared') error, payment = utils.setPaymentDetails('schoolfee',self.student) self.assertEqual(payment.amount_auth, 126200) self.assertEqual(error, None) # NCE student payment can be disabled by # setting the base school fee to -1 IWorkflowState(self.student).setState('returning') configuration = createObject('waeup.SessionConfiguration') self.app['configuration']['2004'].school_fee_base = -1.0 self.certificate.study_mode = 'nce_ft' error, payment = utils.setPaymentDetails('schoolfee',self.student) self.assertEqual(error, u'School fee payment is disabled.') error, payment = utils.setPaymentDetails('clearance',self.student) self.assertEqual(error, u'Acceptance Fee payments not allowed.') IWorkflowState(self.student).setState('cleared') error, payment = utils.setPaymentDetails('clearance',self.student) self.assertEqual(payment.p_level, 100) self.assertEqual(payment.p_session, 2004) self.assertEqual(payment.amount_auth, 120) self.assertEqual(payment.p_item, u'CERT1') self.assertEqual(error, None) self.app['hostels'].accommodation_session = 2005 error, payment = utils.setPaymentDetails('hostel_maintenance',self.student) self.assertEqual(payment, None) self.assertEqual(error, 'No bed space allocated.') self.app['hostels'].accommodation_session = 2004 error, payment = utils.setPaymentDetails('hostel_maintenance',self.student) self.assertEqual(payment.p_level, 100) self.assertEqual(payment.p_session, 2004) self.assertEqual(payment.amount_auth, 876.0) self.assertEqual(payment.p_item, u'My bed coordinates') self.assertEqual(error, None) #error, payment = utils.setPaymentDetails('third_semester',self.student) #self.assertEqual(error, u'Amount could not be determined.') #self.student['studycourse'].current_level = 300 #error, payment = utils.setPaymentDetails('third_semester',self.student) #self.assertEqual(error, u'Amount could not be determined.') #payment = createObject('waeup.StudentOnlinePayment') #payment.p_category = u'schoolfee' #payment.p_session = self.student.current_session #payment.p_item = u'My Certificate' #payment.p_id = u'anyid' #self.student['payments']['anykey'] = payment #payment.p_state = 'paid' #payment.p_level = 300 #error, payment = utils.setPaymentDetails('third_semester',self.student) #self.assertEqual(payment.p_level, 300) #self.assertEqual(payment.p_session, 2004) #self.assertEqual(payment.amount_auth, 7938) #self.assertEqual(payment.p_item, u'') #self.assertEqual(error, None) self.certificate.study_mode = u'nce_sw' error, payment = utils.setPaymentDetails('hostel_maintenance',self.student) self.assertEqual(payment.p_level, 100) self.assertEqual(payment.p_session, 2004) self.assertEqual(payment.amount_auth, 547.5) # 62.5% * 876 self.assertEqual(payment.p_item, u'My bed coordinates') self.assertEqual(error, None) error, payment = utils.setPaymentDetails('bed_allocation',self.student) self.assertEqual(payment.p_level, 100) self.assertEqual(payment.p_session, 2004) self.assertEqual(payment.amount_auth, 150) self.assertEqual(payment.p_item, u'regular_male_fr') self.assertEqual(error, None) error, payment = utils.setPaymentDetails('schoolfee',self.student, 2004, 100) self.assertEqual(error, u'Previous session payment not yet implemented.') return def test_student_start_clearance(self): self.browser.open(self.login_path) self.browser.getControl(name="form.login").value = self.student_id self.browser.getControl(name="form.password").value = 'spwd' self.browser.getControl("Login").click() IWorkflowInfo(self.student).fireTransition('admit') self.browser.open(self.student_path + '/change_portrait') image = open(SAMPLE_IMAGE, 'rb') ctrl = self.browser.getControl(name='passportuploadedit') file_ctrl = ctrl.mech_control file_ctrl.add_file(image, filename='my_photo.jpg') self.browser.getControl( name='upload_passportuploadedit').click() self.browser.open(self.student_path + '/start_clearance') # In Okene the ug students start clearance with activation code ... self.assertTrue('Activation Code:' in self.browser.contents) self.browser.getControl("Start clearance now").click() self.assertTrue('Activation code is invalid' in self.browser.contents) # ... and nce students without. self.certificate.study_mode = 'nce_ft' self.browser.open(self.student_path + '/start_clearance') self.assertFalse('Activation Code:' in self.browser.contents) self.browser.getControl("Start clearance now").click() self.assertTrue( 'Clearance process has been started' in self.browser.contents) def test_open_slips(self): # Managers can open clearance slip self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') self.browser.open(self.student_path + '/view_clearance') self.browser.getLink("Download clearance slip").click() self.assertEqual(self.browser.headers['Status'], '200 Ok') self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') def test_student_accommodation(self): del self.student['accommodation']['2004'] self.certificate.study_mode = 'ug_pt' # Login self.browser.open(self.login_path) self.browser.getControl(name="form.login").value = self.student_id self.browser.getControl(name="form.password").value = 'spwd' self.browser.getControl("Login").click() # Students can book accommodation without AC ... self.browser.open(self.acco_path) IWorkflowInfo(self.student).fireTransition('admit') self.browser.getControl("Book accommodation").click() self.assertFalse('Activation Code:' in self.browser.contents) self.browser.getControl("Create bed ticket").click() # Bed is randomly selected but, since there is only # one bed for this student, we know that self.assertEqual(self.student['accommodation']['2004'].bed_coordinates, 'Hall 1, Block A, Room 101, Bed A (regular_male_fr)') self.assertEqual(self.student['accommodation']['2004'].display_coordinates, '(see payment slip)') # But the bed coordinates are hidden. self.assertFalse('Hall 1, Block A, Room 101, Bed A' in self.browser.contents) self.assertTrue('(see payment slip)' in self.browser.contents) return def test_admission_slip(self): # Login IWorkflowState(self.student).setState('admitted') self.browser.open(self.login_path) self.browser.getControl(name="form.login").value = self.student_id self.browser.getControl(name="form.password").value = 'spwd' self.browser.getControl("Login").click() self.assertFalse( 'Download admission letter' in self.browser.contents) IWorkflowState(self.student).setState('clearance started') self.browser.open(self.student_path) self.assertTrue( 'Download admission letter' in self.browser.contents) # Students can open admission letter self.browser.getLink("Download admission letter").click() self.assertEqual(self.browser.headers['Status'], '200 Ok') self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') path = os.path.join(samples_dir(), 'admission_slip_combined.pdf') open(path, 'wb').write(self.browser.contents) print "Sample PDF admission_slip_combined.pdf written to %s" % path self.certificate.study_mode = 'pd_ft' self.browser.open(self.student_path) self.browser.getLink("Download admission letter").click() path = os.path.join(samples_dir(), 'admission_slip.pdf') open(path, 'wb').write(self.browser.contents) print "Sample PDF admission_slip.pdf written to %s" % path return def test_payment_disabled(self): self.certificate.study_mode = 'nce_ft' IWorkflowState(self.student).setState('cleared') self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') self.browser.open(self.payments_path) self.browser.getLink("Add current session payment ticket").click() self.browser.getControl(name="form.p_category").value = ['schoolfee'] self.browser.getControl("Create ticket").click() self.assertMatches('...ticket created...', self.browser.contents) self.app['configuration']['2004'].payment_disabled = ['sf_nce1'] self.browser.open(self.payments_path) self.browser.getLink("Add current session payment ticket").click() self.browser.getControl(name="form.p_category").value = ['schoolfee'] self.browser.getControl("Create ticket").click() self.assertMatches('...This category of payments has been disabled...', self.browser.contents) self.certificate.study_mode = 'ug_ft' self.browser.open(self.payments_path) self.browser.getLink("Add current session payment ticket").click() self.browser.getControl(name="form.p_category").value = ['schoolfee'] self.browser.getControl("Create ticket").click() self.assertMatches('...ticket created...', self.browser.contents) return def test_student_course_registration(self): IWorkflowState(self.student).setState('school fee paid') self.browser.open(self.login_path) self.browser.getControl(name="form.login").value = self.student_id self.browser.getControl(name="form.password").value = 'spwd' self.browser.getControl("Login").click() # Now students can add the current study level self.browser.getLink("Study Course").click() self.browser.getLink("Add course list").click() self.assertMatches('...Add current level 100 (Year 1)...', self.browser.contents) self.browser.getControl("Create course list now").click() # Students can open the customized pdf course registration slip self.browser.open( self.student_path + '/studycourse/100/course_registration_slip.pdf') self.assertEqual(self.browser.headers['Status'], '200 Ok') self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') path = os.path.join(samples_dir(), 'course_registration_slip.pdf') open(path, 'wb').write(self.browser.contents) print "Sample PDF course_registration_slip.pdf written to %s" % path # Students can open the examination clearance slip if they are # in state courses validated IWorkflowState(self.student).setState('courses validated') self.browser.open(self.student_path + '/studycourse/100') self.browser.getLink("Download 1st semester examination clearance slip").click() self.assertEqual(self.browser.headers['Status'], '200 Ok') self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') path = os.path.join(samples_dir(), 'examination_clearance_slip_1.pdf') open(path, 'wb').write(self.browser.contents) print "Sample PDF examination_clearance_slip_1.pdf written to %s" % path self.browser.open(self.student_path + '/studycourse/100') self.browser.getLink("Download 2nd semester examination clearance slip").click() self.assertEqual(self.browser.headers['Status'], '200 Ok') self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf') path = os.path.join(samples_dir(), 'examination_clearance_slip_2.pdf') open(path, 'wb').write(self.browser.contents) print "Sample PDF examination_clearance_slip_2.pdf written to %s" % path