source: main/waeup.custom/trunk/src/waeup/custom/students/tests.py @ 7889

Last change on this file since 7889 was 7889, checked in by Henrik Bettermann, 13 years ago

First implementation of Interswitch callback validation (work in progress, see also email sent to Jason).

  • Property svn:keywords set to Id
File size: 9.7 KB
Line 
1## $Id: tests.py 7889 2012-03-15 21:53:34Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18import os
19import shutil
20import tempfile
21from hurry.workflow.interfaces import IWorkflowState
22from zope.component.hooks import setSite, clearSite
23from waeup.kofa.app import University
24from waeup.kofa.students.tests.test_browser import StudentsFullSetup
25from waeup.kofa.testing import FunctionalTestCase
26from waeup.kofa.students.batching import StudentProcessor as StudentProcessorBase
27from waeup.custom.students.batching import StudentProcessor
28from waeup.custom.testing import FunctionalLayer
29from waeup.custom.configuration import SessionConfiguration
30
31STUDENT_SAMPLE_DATA = open(
32    os.path.join(os.path.dirname(__file__), 'sample_student_data.csv'),
33    'rb').read()
34
35STUDENT_HEADER_FIELDS = STUDENT_SAMPLE_DATA.split(
36    '\n')[0].split(',')
37
38class StudentImporterTest(FunctionalTestCase):
39    """Perform some batching tests.
40    """
41
42    layer = FunctionalLayer
43
44    def setUp(self):
45        super(StudentImporterTest, self).setUp()
46        # Setup a sample site for each test
47        app = University()
48        self.dc_root = tempfile.mkdtemp()
49        app['datacenter'].setStoragePath(self.dc_root)
50
51        # Prepopulate the ZODB...
52        self.getRootFolder()['app'] = app
53        # we add the site immediately after creation to the
54        # ZODB. Catalogs and other local utilities are not setup
55        # before that step.
56        self.app = self.getRootFolder()['app']
57        # Set site here. Some of the following setup code might need
58        # to access grok.getSite() and should get our new app then
59        setSite(app)
60
61        self.importer_base = StudentProcessorBase()
62        self.importer = StudentProcessor()
63        self.workdir = tempfile.mkdtemp()
64        self.csv_file = os.path.join(self.workdir, 'sample_student_data.csv')
65        open(self.csv_file, 'wb').write(STUDENT_SAMPLE_DATA)
66
67    def tearDown(self):
68        super(StudentImporterTest, self).tearDown()
69        shutil.rmtree(self.workdir)
70        shutil.rmtree(self.dc_root)
71        clearSite()
72        return
73
74    def test_import(self):
75        # We added empty columns 'nationality' and 'lga' to the import file.
76        # The original importer will fail because these fields are required
77        # in the base package.
78        num, num_warns, fin_file, fail_file = self.importer_base.doImport(
79            self.csv_file, STUDENT_HEADER_FIELDS)
80        self.assertEqual(num_warns,3)
81        assert len(self.app['students'].keys()) == 0
82        # The customized importer does not complain since both fields are
83        # not required in the custom package.
84        num, num_warns, fin_file, fail_file = self.importer.doImport(
85            self.csv_file, STUDENT_HEADER_FIELDS)
86        self.assertEqual(num_warns,0)
87        assert len(self.app['students'].keys()) == 3
88        shutil.rmtree(os.path.dirname(fin_file))
89
90
91class StudentUITests(StudentsFullSetup):
92    """Tests for customized student class views and pages
93    """
94
95    layer = FunctionalLayer
96
97    def callback_url(self, payment_url, resp, apprAmt):
98        return payment_url + (
99            '/callback?echo=' +
100            '&resp=%s' +
101            '&desc=Something went wrong' +
102            '&txnRef=p1331792385335' +
103            '&payRef=' + '&retRef=' +
104            '&cardNum=0' +
105            '&apprAmt=%s' +
106            '&url=http://xyz') % (resp, apprAmt)
107
108    def test_manage_payments(self):
109        # Add missing configuration data
110        self.app['configuration']['2004'].gown_fee = 150
111        self.app['configuration']['2004'].transfer_fee = 90
112        self.app['configuration']['2004'].clearance_fee = 120
113        self.app['configuration']['2004'].maint_fee = 180
114
115        # Managers can add online payment tickets
116        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
117        self.browser.open(self.payments_student_path)
118        self.browser.getControl("Add online payment ticket").click()
119        self.browser.getControl("Create ticket").click()
120        self.assertMatches('...Amount could not be determined...',
121                           self.browser.contents)
122        IWorkflowState(self.student).setState('cleared')
123        self.browser.open(self.payments_student_path + '/addop')
124        self.browser.getControl("Create ticket").click()
125        self.assertMatches('...ticket created...',
126                           self.browser.contents)
127        ctrl = self.browser.getControl(name='val_id')
128        value = ctrl.options[0]
129        self.browser.getLink(value).click()
130        self.assertMatches('...Amount Authorized...',
131                           self.browser.contents)
132        payment_url = self.browser.url
133       
134        # Manager can access InterswitchForm
135        self.browser.getLink("CollegePAY", index=0).click()
136        self.assertMatches('...Total Amount Authorized:...',
137                           self.browser.contents)
138        self.assertMatches(
139            '...<input type="hidden" name="amount" value="4000000" />...',
140            self.browser.contents)
141
142        # Manager receives valid callback
143        #self.browser.open(payment_url)
144        #self.browser.getLink("Request CollegePAY callback").click()
145
146        self.browser.open(self.callback_url(payment_url, 'XX', '300'))
147        self.assertMatches('...Unsuccessful callback: Something went wrong...',
148                          self.browser.contents)
149        self.assertMatches('...Failed...',
150                           self.browser.contents)
151        self.browser.open(self.payments_student_path + '/addop')
152        self.browser.getControl("Create ticket").click()
153        ctrl = self.browser.getControl(name='val_id')
154
155        #value = ctrl.options[1]
156        #self.browser.getLink(value).click()
157        #self.assertMatches('...Amount Authorized...',
158        #                   self.browser.contents)
159        #payment_url = self.browser.url
160
161        self.browser.open(payment_url + '/callback')
162        self.assertMatches('...Unsuccessful callback: No query string...',
163                          self.browser.contents)
164        self.assertMatches('...Failed...',
165                           self.browser.contents)
166        #print self.browser.contents
167        self.browser.open(self.callback_url(payment_url, '00', '300'))
168        self.assertMatches('...Valid callback received...',
169                          self.browser.contents)
170        self.browser.open(self.manage_student_path)
171        self.browser.getControl(
172            name="transition").value = ['pay_first_school_fee']
173        self.browser.getControl("Save").click()
174        # Reset to returning
175        self.browser.getControl(name="transition").value = ['reset6']
176        self.browser.getControl("Save").click()
177        self.browser.open(self.payments_student_path + '/addop')
178        self.browser.getControl("Create ticket").click()
179        self.assertMatches('...This type of payment has already been made...',
180                           self.browser.contents)
181        # Remove all payments so that we can add a school fee payment again
182        keys = [i for i in self.student['payments'].keys()]
183        for payment in keys:
184            del self.student['payments'][payment]
185        self.browser.open(self.payments_student_path + '/addop')
186        self.browser.getControl("Create ticket").click()
187        self.assertMatches('...ticket created...',
188                           self.browser.contents)
189        self.browser.open(self.payments_student_path + '/addop')
190        self.browser.getControl(name="form.p_category").value = ['gown']
191        self.browser.getControl("Create ticket").click()
192        self.browser.open(self.payments_student_path + '/addop')
193        self.browser.getControl(name="form.p_category").value = ['transfer']
194        self.browser.getControl("Create ticket").click()
195        self.browser.open(self.payments_student_path + '/addop')
196        self.browser.getControl(
197            name="form.p_category").value = ['bed_allocation']
198        self.browser.getControl("Create ticket").click()
199        self.browser.open(self.payments_student_path + '/addop')
200        self.browser.getControl(
201            name="form.p_category").value = ['hostel_maintenance']
202        self.browser.getControl("Create ticket").click()
203        self.browser.open(self.payments_student_path + '/addop')
204        self.browser.getControl(name="form.p_category").value = ['clearance']
205        self.browser.getControl("Create ticket").click()
206        self.certificate.study_mode = 'ug_pt'
207        self.browser.open(self.payments_student_path + '/addop')
208        self.browser.getControl(name="form.p_category").value = ['schoolfee']
209        self.browser.getControl("Create ticket").click()
210        self.assertMatches('...Amount could not be determined...',
211                           self.browser.contents)
212
213        # If the session configuration doesn't exist and error message will
214        # be shown
215        del self.app['configuration']['2004']
216        self.browser.open(self.payments_student_path)
217        self.browser.getControl("Add online payment ticket").click()
218        self.browser.getControl("Create ticket").click()
219        self.assertMatches('...Session configuration object is not...',
220                           self.browser.contents)
221
222
Note: See TracBrowser for help on using the repository browser.