## $Id: tests.py 14329 2016-12-09 06:46:14Z 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 grok
import pytz
from datetime import datetime, date, timedelta
from hurry.workflow.interfaces import IWorkflowState
from zope.component import createObject, getUtility
from zope.catalog.interfaces import ICatalog
from zope.event import notify
from waeup.kofa.applicants.container import ApplicantsContainer
from waeup.kofa.university.faculty import Faculty
from waeup.kofa.university.department import Department
from waeup.kofa.students.tests.test_browser import StudentsFullSetup
from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
from waeup.kofa.configuration import SessionConfiguration
from waeup.kwarapoly.testing import FunctionalLayer
from waeup.kwarapoly.students.payments import CustomStudentOnlinePayment

# Also run tests that send requests to external servers?
#   If you enable this, please make sure the external services
#   do exist really and are not bothered by being spammed by a test programme.
EXTERNAL_TESTS = False

def external_test(func):
    if not EXTERNAL_TESTS:
        myself = __file__
        if myself.endswith('.pyc'):
            myself = myself[:-2]
        print "WARNING: external tests are skipped!"
        print "WARNING: edit %s to enable them." % myself
        return
    return func


class InterswitchTestsStudents(StudentsFullSetup):
    """Tests for the Interswitch payment gateway.
    """

    layer = FunctionalLayer

    def setUp(self):
        super(InterswitchTestsStudents, self).setUp()

        # Create at least one Kwarapoly faculty
        self.app['faculties']['CPGS'] = Faculty(code='CPGS')
        self.app['faculties']['CPGS']['dep1'] = Department(code='dep1')
        self.certificate2 = createObject('waeup.Certificate')
        self.certificate2.code = u'CERT2'
        self.certificate2.application_category = 'basic'
        self.certificate2.study_mode = 'nd_ft'
        self.certificate2.start_level = 100
        self.certificate2.end_level = 300
        self.app['faculties']['CPGS']['dep1'].certificates.addCertificate(
            self.certificate2)
        # Set study course attributes of test student
        self.student['studycourse'].certificate = self.certificate2
        self.student['studycourse'].current_session = 2004
        self.student['studycourse'].entry_session = 2004
        self.student['studycourse'].current_verdict = 'A'
        self.student['studycourse'].current_level = 100
        # Set local lga
        self.student.lga = u'kwara_asa'
        # Update the catalog
        notify(grok.ObjectModifiedEvent(self.student))

    def test_schoolfee_ticket_creation(self):
        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
        self.browser.open(self.payments_path)
        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('...Book and pay for accommodation first...',
                           self.browser.contents)
        # We add a fake maint. payment ticket to meet the condition
        maint_payment = CustomStudentOnlinePayment()
        self.student['payments']['any_key'] = maint_payment
        maint_payment.p_category = 'hostel_maintenance'
        maint_payment.p_state = 'unpaid'
        maint_payment.p_session = 2004
        self.browser.getControl(name="form.p_category").value = ['schoolfee']
        self.browser.getControl("Create ticket").click()
        self.assertMatches('...Book and pay for accommodation first...',
                           self.browser.contents)
        # Ticket must be paid
        maint_payment.p_state = 'paid'
        self.browser.getControl(name="form.p_category").value = ['schoolfee']
        self.browser.getControl("Create ticket").click()
        self.assertMatches('...ticket created...',
                           self.browser.contents)
        ctrl = self.browser.getControl(name='val_id')
        self.value = ctrl.options[1]
        self.browser.getLink(self.value).click()
        self.assertMatches('...Amount Authorized...',
                           self.browser.contents)
        self.assertTrue('<span>55500.0</span>' in self.browser.contents)
        self.payment_url = self.browser.url


#    def callback_url(self, payment_url, resp, apprAmt):
#        return payment_url + (
#            '/isw_callback?echo=' +
#            '&resp=%s' +
#            '&desc=Something went wrong' +
#            '&txnRef=p1331792385335' +
#            '&payRef=' + '&retRef=' +
#            '&cardNum=0' +
#            '&apprAmt=%s' +
#            '&url=http://xyz') % (resp, apprAmt)

    def test_interswitch_form(self):

        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
        self.browser.open(self.payments_path)
        # In KwaraPoly only returning students can create school fee payment
        # without haveing paid accommodation fee
        IWorkflowState(self.student).setState('returning')
        configuration = createObject('waeup.SessionConfiguration')
        configuration.academic_session = 2005
        self.app['configuration'].addSessionConfiguration(configuration)
        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)
        ctrl = self.browser.getControl(name='val_id')
        self.value = ctrl.options[0]
        self.browser.getLink(self.value).click()
        self.assertMatches('...Amount Authorized...', self.browser.contents)
        self.assertTrue(
            '<span>32500.0</span>' in self.browser.contents)
        self.payment_url = self.browser.url

        # Manager can access InterswitchForm
        self.assertEqual(self.student['payments'][self.value].provider_amt, 0.0)
        self.assertEqual(self.student['payments'][self.value].gateway_amt, 0.0)
        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 0.0)
        self.browser.getLink("CollegePAY", index=0).click()
        # Split amounts have been set.
        self.assertEqual(self.student['payments'][self.value].provider_amt, 1200.0)
        self.assertEqual(self.student['payments'][self.value].gateway_amt, 300.0)
        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1800.0)
        self.assertMatches('...Total Amount Authorized:...',
                           self.browser.contents)
        self.assertTrue(
            '<input type="hidden" name="amount" value="3250000" />' in
            self.browser.contents)
        self.assertTrue(
            'item_name="School Fee" item_amt="2920000" bank_id="76" acct_num="0838798044"' in
            self.browser.contents)
        self.assertTrue(
            'item_name="Dalash" item_amt="180000" bank_id="117" acct_num="1013196791"' in
            self.browser.contents)
        self.assertTrue(
            'item_name="BT Education" item_amt="120000" bank_id="117" acct_num="1010764827"' in
            self.browser.contents)

        # Let's do the same for maintenance fee payment

        self.browser.open(self.payments_path)
        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('...You have not yet booked accommodation...',
                           self.browser.contents)
        # Students have to book bed first
        self.browser.open(self.acco_path)
        IWorkflowState(self.student).setState('admitted')
        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.assertMatches('...Hall 1, Block A, Room 101, Bed A...',
                           self.browser.contents)
        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)
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[1]
        self.browser.getLink(value).click()
        self.assertMatches('...Amount Authorized...',
                           self.browser.contents)
        # Maint fee is taken from the hostel object
        self.assertTrue('<span>876.0</span>' in self.browser.contents)
        self.payment_url = self.browser.url
        # Manager can access InterswitchForm
        self.browser.getLink("CollegePAY", index=0).click()
        # Split amounts have been set.
        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
        # The total amount to be processed by Interswitch
        # has been reduced by the Interswitch fee of 150 Nairas
        self.assertMatches('...Total Amount Authorized:...',
                           self.browser.contents)
        self.assertTrue(
            '<input type="hidden" name="pay_item_id" value="102" />' in
            self.browser.contents)
        self.assertTrue(
            '<input type="hidden" name="amount" value="87600" />' in
            self.browser.contents)
        self.assertTrue(
            'item_name="Hostel Maintenance" item_amt="57600" bank_id="76" acct_num="0838798044"' in
            self.browser.contents)

        # Create carryover ticket
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(name="form.p_category").value = ['carryover1']
        self.browser.getControl("Create ticket").click()
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[2]
        self.browser.getLink(value).click()
        self.assertTrue('<span>6000.0</span>' in self.browser.contents)
        # Manager can access InterswitchForm
        self.browser.getLink("CollegePAY", index=0).click()
        # Split amounts have been set.
        self.assertEqual(self.student['payments'][self.value].provider_amt, 1200.0)
        self.assertEqual(self.student['payments'][self.value].gateway_amt, 300.0)
        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1800.0)
        self.assertTrue('<input type="hidden" name="pay_item_id" value="101" />' in
                           self.browser.contents)
        self.assertMatches('...Total Amount Authorized:...',
                           self.browser.contents)
        self.assertTrue(
            '<input type="hidden" name="amount" value="600000" />' in
            self.browser.contents)
        self.assertTrue(
            'item_name="One Carry-Over" item_amt="270000" bank_id="76" acct_num="0838798044"' in
            self.browser.contents)
        self.assertTrue(
            'item_name="Dalash" item_amt="180000" bank_id="117" acct_num="1013196791"' in
            self.browser.contents)
        self.assertTrue(
            'item_name="BT Education" item_amt="120000" bank_id="117" acct_num="1010764827"' in
            self.browser.contents)

    def test_interswitch_form_new_payment_cats(self):
        # only a few categories covered

        self.app['configuration']['2004'].certificate_fee = 6800.0
        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(name="form.p_category").value = ['certificate']
        self.browser.getControl("Create ticket").click()
        self.assertMatches('...ticket created...', self.browser.contents)
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[0]
        self.browser.getLink(value).click()
        self.assertMatches('...Amount Authorized...', self.browser.contents)
        self.assertTrue('<span>6800.0</span>' in self.browser.contents)
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertEqual(self.student['payments'][value].amount_auth, 6800.0)
        self.assertEqual(self.student['payments'][value].provider_amt, 300.0)
        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
        self.assertEqual(self.student['payments'][value].thirdparty_amt, 200.0)

        self.app['configuration']['2004'].transcript_local_fee = 6000.0
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(name="form.p_category").value = ['transcript_local']
        self.browser.getControl("Create ticket").click()
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[1]
        self.browser.getLink(value).click()
        self.assertMatches('...Amount Authorized...', self.browser.contents)
        self.assertTrue('<span>6000.0</span>' in self.browser.contents)
        self.payment_url = self.browser.url
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertEqual(self.student['payments'][value].amount_auth, 6000.0)
        self.assertEqual(self.student['payments'][value].provider_amt, 300.0)
        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
        self.assertEqual(self.student['payments'][value].thirdparty_amt, 200.0)

        self.app['configuration']['2004'].loss_idcard_fee = 1015.0
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(name="form.p_category").value = ['loss_idcard']
        self.browser.getControl("Create ticket").click()
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[2]
        self.browser.getLink(value).click()
        self.assertMatches('...Amount Authorized...', self.browser.contents)
        self.assertTrue(
            '<span>1015.0</span>' in self.browser.contents)
        self.payment_url = self.browser.url
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertEqual(self.student['payments'][value].amount_auth, 1015.0)
        self.assertEqual(self.student['payments'][value].provider_amt, 9.0)
        self.assertEqual(self.student['payments'][value].gateway_amt, 15.22)
        self.assertEqual(self.student['payments'][value].thirdparty_amt, 6.0)

        self.app['configuration']['2004'].loss_examcard_fee = 500.0
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(name="form.p_category").value = ['loss_examcard']
        self.browser.getControl("Create ticket").click()
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[3]
        self.browser.getLink(value).click()
        self.assertMatches('...Amount Authorized...', self.browser.contents)
        self.assertTrue('<span>500.0</span>' in self.browser.contents)
        self.payment_url = self.browser.url
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertEqual(self.student['payments'][value].amount_auth, 500.0)
        self.assertEqual(self.student['payments'][value].provider_amt, 4.5)
        self.assertEqual(self.student['payments'][value].gateway_amt, 7.5)
        self.assertEqual(self.student['payments'][value].thirdparty_amt, 3)

        self.app['configuration']['2004'].change_inst_fee = 6000.0
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(name="form.p_category").value = ['change_inst']
        self.browser.getControl("Create ticket").click()
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[4]
        self.browser.getLink(value).click()
        self.assertMatches('...Amount Authorized...', self.browser.contents)
        self.assertTrue('<span>6000.0</span>' in self.browser.contents)
        self.payment_url = self.browser.url
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertEqual(self.student['payments'][value].amount_auth, 6000.0)
        self.assertEqual(self.student['payments'][value].provider_amt, 300.0)
        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
        self.assertEqual(self.student['payments'][value].thirdparty_amt, 200.0)

        self.app['configuration']['2004'].loss_result_fee = 7000.0
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(name="form.p_category").value = ['loss_result']
        self.browser.getControl("Create ticket").click()
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[5]
        self.browser.getLink(value).click()
        self.assertMatches('...Amount Authorized...', self.browser.contents)
        self.assertTrue('<span>7000.0</span>' in self.browser.contents)
        self.payment_url = self.browser.url
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertEqual(self.student['payments'][value].amount_auth, 7000.0)
        self.assertEqual(self.student['payments'][value].provider_amt, 300.0)
        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
        self.assertEqual(self.student['payments'][value].thirdparty_amt, 200.0)

        self.app['configuration']['2004'].loss_idcard_fee = 1900.0
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(name="form.p_category").value = ['loss_idcard']
        self.browser.getControl("Create ticket").click()
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[6]
        self.browser.getLink(value).click()
        self.assertMatches('...Amount Authorized...', self.browser.contents)
        self.assertTrue('<span>1900.0</span>' in self.browser.contents)
        self.payment_url = self.browser.url
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertEqual(self.student['payments'][value].amount_auth, 1900.0)
        self.assertEqual(self.student['payments'][value].provider_amt, 9.0)
        self.assertEqual(self.student['payments'][value].gateway_amt, 28.5)
        self.assertEqual(self.student['payments'][value].thirdparty_amt, 6.0)


    def test_interswitch_form_ticket_expired(self):
        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
        acc_payment = createObject('waeup.StudentOnlinePayment')
        acc_payment.p_state = 'unpaid'
        acc_payment.p_category = 'clearance'
        acc_payment.p_id = 'xyz'
        acc_payment.pay_item_id = '123'
        acc_payment.amount_auth = 876.0
        self.student['payments']['xyz'] = acc_payment
        self.browser.open(self.payments_path + '/xyz')
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertTrue('<input type="hidden" name="pay_item_id" value="146" />'
                           in self.browser.contents)
        self.assertMatches('...Total Amount Authorized:...',
                           self.browser.contents)
        self.assertEqual(self.student.current_mode, 'nd_ft')
        self.assertTrue(
            '<input type="hidden" name="amount" value="87600" />' in
            self.browser.contents)
        delta = timedelta(days=8)
        acc_payment.creation_date -= delta
        self.browser.open(self.payments_path + '/xyz')
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertMatches(
            '...This payment ticket is too old. Please create a new ticket...',
            self.browser.contents)
        delta = timedelta(days=2)
        acc_payment.creation_date += delta
        self.browser.open(self.payments_path + '/xyz')
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertMatches('...Total Amount Authorized:...',
                           self.browser.contents)

    @external_test
    def test_webservice(self):
        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
        IWorkflowState(self.student).setState('cleared')
        # We add a fake maint. payment ticket to meet the condition
        maint_payment = CustomStudentOnlinePayment()
        self.student['payments']['any_key'] = maint_payment
        maint_payment.p_category = 'hostel_maintenance'
        maint_payment.p_state = 'paid'
        maint_payment.p_session = 2004
        # We create the school fee payment ticket
        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)
        ctrl = self.browser.getControl(name='val_id')
        self.value = ctrl.options[1]
        self.browser.getLink(self.value).click()
        self.payment_url = self.browser.url
        # First we have open InterswitchPageStudent to set provider_amt
        # and gateway_amt
        self.browser.open(self.payment_url + '/goto_interswitch')
        # Now we can call the webservice
        self.browser.open(self.payment_url + '/request_webservice')
        self.assertMatches('...Unsuccessful callback...',
                          self.browser.contents)
        # The payment is now in state failed ...
        self.assertMatches('...<span>Failed</span>...',
                          self.browser.contents)
        # ... and the catalog has been updated
        cat = getUtility(ICatalog, name='payments_catalog')
        results = list(
            cat.searchResults(p_state=('failed', 'failed')))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].p_state, 'failed')

        # Let's replace the p_id with a valid p_id of the Kwarapoly
        # live system. This is definitely not an appropriate
        # solution for testing, but we have no choice since
        # Interswitch doesn't provide any interface
        # for testing.
        payment = self.student['payments'][self.value]
        payment.p_id = 'p3543612043224'
        self.browser.open(self.payment_url + '/request_webservice')
        self.assertMatches('...Callback amount does not match...',
                          self.browser.contents)
        # The payment is now in state failed ...
        self.assertMatches('...<span>Failed</span>...',
                          self.browser.contents)
        # Let's replace the amount autorized with the amount of the
        # live system payment
        payment.amount_auth = payment.r_amount_approved
        self.browser.open(self.payment_url + '/request_webservice')
        self.assertMatches('...Successful payment...',
                          self.browser.contents)
        # The payment is now in state paid ...
        self.assertMatches('...<span>Paid</span>...',
                          self.browser.contents)
        # ... and the catalog has been updated
        cat = getUtility(ICatalog, name='payments_catalog')
        results = list(
            cat.searchResults(p_state=('paid', 'paid')))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].p_state, 'paid')
        # Approval is logged in students.log ...
        logfile = os.path.join(
            self.app['datacenter'].storage, 'logs', 'students.log')
        logcontent = open(logfile).read()
        self.assertTrue(
            'zope.mgr - '
            'waeup.kwarapoly.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageStudent - '
            'W1000000 - successful schoolfee payment: p3543612043224\n'
            in logcontent)
        # ... and in payments.log
        logfile = os.path.join(
            self.app['datacenter'].storage, 'logs', 'payments.log')
        logcontent = open(logfile).read()
        self.assertTrue(
            '"zope.mgr",W1000000,p3543612043224,schoolfee,'
            '52100.0,00,1200.0,300.0,1800.0,,,\n'
            in logcontent)


class InterswitchTestsApplicants(ApplicantsFullSetup):
    """Tests for the Interswitch payment gateway.
    """

    layer = FunctionalLayer

    def setUp(self):
        super(InterswitchTestsApplicants, self).setUp()
        configuration = SessionConfiguration()
        configuration.academic_session = datetime.now().year - 2
        self.app['configuration'].addSessionConfiguration(configuration)
        self.configuration = configuration
        # Create at least one Kwarapoly faculty
        self.app['faculties']['CPGS'] = Faculty(code='CPGS')
        self.app['faculties']['CPGS']['dep1'] = Department(code='dep1')
        self.certificate2 = createObject('waeup.Certificate')
        self.certificate2.code = u'CERT2'
        self.certificate2.application_category = 'ndft'
        self.certificate2.study_mode = 'nd_ft'
        self.certificate2.start_level = 100
        self.certificate2.end_level = 300
        self.app['faculties']['CPGS']['dep1'].certificates.addCertificate(
            self.certificate2)
        self.applicantscontainer.application_category = 'ndft'
        self.applicant.applicant_id = u'nd_anything'
        
        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
        self.browser.open(self.manage_path)
        #IWorkflowState(self.student).setState('started')
        super(InterswitchTestsApplicants, self).fill_correct_values()
        self.browser.getControl(name="form.course1").value = ['CERT2']
        self.applicantscontainer.application_fee = 3333.0
        self.browser.getControl(name="form.nationality").value = ['NG']
        self.browser.getControl(name="transition").value = ['start']
        self.browser.getControl("Save").click()
        self.browser.getControl("Add online").click()
        self.assertMatches('...ticket created...',
                           self.browser.contents)
        self.assertMatches('...Amount Authorized...',
                           self.browser.contents)
        self.assertTrue('<span>3333.0</span>' in self.browser.contents)
        self.payment_url = self.browser.url


    def test_interswitch_form(self):

        # Manager can access InterswitchForm
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertMatches('...Total Amount Authorized:...',
                           self.browser.contents)
        self.assertTrue(
            '<input type="hidden" name="amount" value="333300" />'
            in self.browser.contents)
        self.assertTrue(
            '<item_detail item_id="1" item_name="Application" '
            'item_amt="253300" bank_id="76" acct_num="0838798044" />'
            in self.browser.contents)

        # Meanwhile hndft fee goes to same account
        self.applicant.applicant_id = u'hnd_anything'
        self.browser.open(self.manage_path)
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[0]
        self.browser.getLink(value).click()
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertTrue(
            '<item_detail item_id="1" item_name="Application" '
            'item_amt="253300" bank_id="76" acct_num="0838798044" />'
            in self.browser.contents)
        # Commission or bribe?
        self.assertTrue(
            '<item_detail item_id="2" item_name="Dalash" item_amt="20000" '
            'bank_id="117" acct_num="1013196791" />'
            in self.browser.contents)
        self.assertTrue(
            '<item_detail item_id="3" item_name="BT Education" '
            'item_amt="30000" bank_id="117" acct_num="1010764827" />'
            in self.browser.contents)

        # prehndft fee goes to another account and has other split data
        self.applicant.applicant_id = u'prehnd_anything'
        self.browser.open(self.manage_path)
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[0]
        self.browser.getLink(value).click()
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertTrue(
            '<item_detail item_id="1" item_name="Application" '
            'item_amt="303300" bank_id="76" acct_num="0838798044" />'
            in self.browser.contents)
        self.assertFalse('Dalash' in self.browser.contents)
        self.assertTrue(
            '<item_detail item_id="2" item_name="BT Education" '
            'item_amt="26250" bank_id="117" acct_num="1010764827" />'
            in self.browser.contents)

        # prejambites fee goes to another account
        self.applicant.applicant_id = u'prejambites_anything'
        self.browser.open(self.manage_path)
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[0]
        self.browser.getLink(value).click()
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertTrue(
            '<item_detail item_id="1" item_name="Application" '
            'item_amt="303300" bank_id="76" acct_num="0838798044" />'
            in self.browser.contents)
        self.assertFalse('Dalash' in self.browser.contents)
        #self.assertFalse('BT Education' in self.browser.contents)
        self.assertTrue(
            '<item_detail item_id="2" item_name="BT Education" '
            'item_amt="26250" bank_id="117" acct_num="1010764827" />'
            in self.browser.contents)
        self.assertTrue(
            '<input type="hidden" name="pay_item_id" value="104" />'
            in self.browser.contents)

        # putme goes into the prejambites account
        self.applicant.applicant_id = u'putme_anything'
        self.browser.open(self.manage_path)
        ctrl = self.browser.getControl(name='val_id')
        value = ctrl.options[0]
        self.browser.getLink(value).click()
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertTrue(
            '<item_detail item_id="1" item_name="Application" '
            'item_amt="253300" bank_id="76" acct_num="0838798044" />'
            in self.browser.contents)
        self.assertTrue(
            '<item_detail item_id="2" item_name="Dalash" item_amt="20000" '
            'bank_id="117" acct_num="1013196791" />'
            in self.browser.contents)
        self.assertTrue(
            '<item_detail item_id="3" item_name="BT Education" '
            'item_amt="30000" bank_id="117" acct_num="1010764827" />'
            in self.browser.contents)
        self.assertTrue(
            '<input type="hidden" name="pay_item_id" value="104" />'
            in self.browser.contents)

    def test_interswitch_form_ticket_expired(self):
        # Manager can access InterswitchForm
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertMatches('...Total Amount Authorized:...',
                           self.browser.contents)
        self.assertTrue(
            '<input type="hidden" name="amount" value="333300" />'
            in self.browser.contents)
        self.assertTrue(
            '<item_detail item_id="1" item_name="Application" '
            'item_amt="253300" bank_id="76" acct_num="0838798044" />'
            in self.browser.contents)
        delta = timedelta(days=8)
        self.applicant.values()[0].creation_date -= delta
        self.browser.open(self.payment_url)
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertMatches(
            '...This payment ticket is too old. Please create a new ticket...',
            self.browser.contents)

    def prepare_special_container(self):
        # Add special application container
        container_name = u'special%s' % (datetime.now().year - 2)
        applicantscontainer = ApplicantsContainer()
        applicantscontainer.code = container_name
        applicantscontainer.prefix = 'special'
        applicantscontainer.year = datetime.now().year - 2
        applicantscontainer.title = u'This is a special app container'
        applicantscontainer.application_category = 'no'
        applicantscontainer.mode = 'create'
        delta = timedelta(days=10)
        applicantscontainer.startdate = datetime.now(pytz.utc) - delta
        applicantscontainer.enddate = datetime.now(pytz.utc) + delta
        applicantscontainer.strict_deadline = True
        self.app['applicants'][container_name] = applicantscontainer
        # Add an applicant
        applicant = createObject('waeup.Applicant')
        # reg_number is the only field which has to be preset here
        # because managers are allowed to edit this required field
        applicant.reg_number = u'12345'
        applicant.firstname = u'Vorname'
        applicant.lastname = u'Nachname'
        applicant.email = 'aa@aa.aa'
        applicant.special_application = u'transcript_local'
        applicant.applicant_id = u'special_anything'
        self.app['applicants'][container_name].addApplicant(applicant)
        self.special_applicant = applicant
        self.configuration.transcript_local_fee = 5300.0
        self.special_manage_path = 'http://localhost/app/applicants/%s/%s/%s' % (
            container_name, applicant.application_number, 'manage')

    def test_interswitch_form_special(self):
        self.prepare_special_container()
        self.browser.open(self.special_manage_path)
        self.browser.getControl("Add online").click()
        self.assertMatches('...ticket created...',
                           self.browser.contents)
        self.browser.getLink("CollegePAY", index=0).click()
        self.assertTrue(
            '<item_detail item_id="1" item_name="ND Transcript (local)" '
            'item_amt="450000" bank_id="76" acct_num="0838798044" />'
            in self.browser.contents)

        self.special_applicant.special_application = u'log_book'
        self.configuration.log_book_fee = 570.5
        self.browser.open(self.special_manage_path)
        self.browser.getControl("Add online").click()
        self.assertMatches('...ticket created...',
                           self.browser.contents)
        self.browser.getLink("CollegePAY", index=0).click()
        # The university gets 570.5 - (1.5% x 570.5) - 3 - 4.5
        self.assertTrue(
            '<item_detail item_id="1" item_name="Log Book" '
            'item_amt="55444" bank_id="76" acct_num="0838798044" />'
            in self.browser.contents)


    @external_test
    def test_webservice(self):
        self.prepare_special_container()
        IWorkflowState(self.special_applicant).setState('started')
        self.browser.open(self.special_manage_path)
        self.browser.getControl("Add online").click()
        payment_url = self.browser.url
        self.browser.open(payment_url + '/request_webservice')
        self.assertMatches('...Unsuccessful callback...',
                          self.browser.contents)
        # The payment is now in state failed
        self.assertMatches('...<span>Failed</span>...',
                          self.browser.contents)
        # Let's replace the p_id with a valid p_id of the Kwarapoly
        # live system. This is definitely not an appropriate
        # solution for testing, but we have no choice since
        # Interswitch doesn't provide any interface
        # for testing.
        p_id = self.special_applicant.keys()[0]
        payment = self.special_applicant[p_id]
        payment.p_id = 'p3543612043224'
        self.browser.open(payment_url + '/request_webservice')
        self.assertMatches('...Callback amount does not match...',
                          self.browser.contents)
        payment.amount_auth = payment.r_amount_approved

        self.browser.open(payment_url + '/request_webservice')
        self.assertMatches('...Successful payment...',
                          self.browser.contents)
        # The payment is now in state paid ...
        self.assertMatches('...<span>Paid</span>...',
                          self.browser.contents)
        # ... and the catalog has been updated
        cat = getUtility(ICatalog, name='payments_catalog')
        results = list(
            cat.searchResults(p_state=('paid', 'paid')))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].p_state, 'paid')
        # Approval is logged in applicants.log ...
        logfile = os.path.join(
            self.app['datacenter'].storage, 'logs', 'applicants.log')
        logcontent = open(logfile).read()
        self.assertTrue(
            'zope.mgr - waeup.kwarapoly.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageApplicant'
            ' - special_anything - successful payment: p3543612043224\n'
            in logcontent)
        # ... and in payments.log
        logfile = os.path.join(
            self.app['datacenter'].storage, 'logs', 'payments.log')
        logcontent = open(logfile).read()
        self.assertTrue(
            '"zope.mgr",special_anything,p3543612043224,transcript_local,52100.0,'
            '00,0.0,0.0,0.0,,,\n'
            in logcontent)
        self.assertEqual(self.applicant.state, 'started')
        # Special Payment applicant can add new payment
        self.browser.open(self.edit_path)
        self.assertTrue('Add online payment ticket' in self.browser.contents)
