## $Id: test_browser.py 8020 2012-04-02 11:05:40Z 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 hurry.workflow.interfaces import IWorkflowState
from zope.component.hooks import setSite, clearSite
from waeup.kofa.app import University
from waeup.kofa.students.tests.test_browser import StudentsFullSetup
from waeup.kofa.testing import FunctionalTestCase
from waeup.kofa.students.batching import StudentProcessor as StudentProcessorBase
from waeup.uniben.students.batching import StudentProcessor
from waeup.uniben.testing import FunctionalLayer

STUDENT_SAMPLE_DATA = open(
    os.path.join(os.path.dirname(__file__), 'sample_student_data.csv'),
    'rb').read()

STUDENT_HEADER_FIELDS = STUDENT_SAMPLE_DATA.split(
    '\n')[0].split(',')

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)

        self.processor_base = StudentProcessorBase()
        self.processor = StudentProcessor()
        self.workdir = tempfile.mkdtemp()
        self.csv_file = os.path.join(self.workdir, 'sample_student_data.csv')
        open(self.csv_file, 'wb').write(STUDENT_SAMPLE_DATA)

    def tearDown(self):
        super(StudentProcessorTest, self).tearDown()
        shutil.rmtree(self.workdir)
        shutil.rmtree(self.dc_root)
        clearSite()
        return

    def test_import(self):
        # We have an empty column 'date_of_birth' in  the import file.
        # The original processor will fail because 'date_of_birth' is required
        # in the base package.
        num, num_warns, fin_file, fail_file = self.processor_base.doImport(
            self.csv_file, STUDENT_HEADER_FIELDS)
        self.assertEqual(num_warns,3)
        assert len(self.app['students'].keys()) == 0
        # The customized processor does not complain since 'date_of_birth' is
        # not required in the custom package.
        num, num_warns, fin_file, fail_file = self.processor.doImport(
            self.csv_file, STUDENT_HEADER_FIELDS)
        #print open(fail_file).read()
        self.assertEqual(num_warns,0)
        assert len(self.app['students'].keys()) == 3
        shutil.rmtree(os.path.dirname(fin_file))


class StudentUITests(StudentsFullSetup):
    """Tests for customized student class views and pages
    """

    layer = FunctionalLayer

    def test_manage_payments(self):
        # Add missing configuration data
        self.app['configuration']['2004'].gown_fee = 150.0
        self.app['configuration']['2004'].transfer_fee = 90.0
        self.app['configuration']['2004'].clearance_fee = 120.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.getControl("Add online payment ticket").click()
        self.browser.getControl("Create ticket").click()
        self.assertMatches('...Amount could not be determined...',
                           self.browser.contents)
        IWorkflowState(self.student).setState('cleared')
        self.browser.open(self.payments_path + '/addop')
        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)
        # Set ticket paid
        ticket = self.student['payments'].items()[0][1]
        ticket.p_state = 'paid'
        IWorkflowState(self.student).setState('returning')
        self.browser.open(self.payments_path + '/addop')
        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("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 = ['gown']
        self.browser.getControl("Create ticket").click()
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(name="form.p_category").value = ['transfer']
        self.browser.getControl("Create ticket").click()
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(
            name="form.p_category").value = ['bed_allocation']
        self.browser.getControl("Create ticket").click()
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(
            name="form.p_category").value = ['hostel_maintenance']
        self.browser.getControl("Create ticket").click()
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(name="form.p_category").value = ['clearance']
        self.browser.getControl("Create ticket").click()
        self.certificate.study_mode = 'ug_pt'
        self.browser.open(self.payments_path + '/addop')
        self.browser.getControl(name="form.p_category").value = ['schoolfee']
        self.browser.getControl("Create ticket").click()
        self.assertMatches('...Amount could not be determined...',
                           self.browser.contents)

        # If the session configuration doesn't exist and error message will
        # be shown
        del self.app['configuration']['2004']
        self.browser.open(self.payments_path)
        self.browser.getControl("Add online payment ticket").click()
        self.browser.getControl("Create ticket").click()
        self.assertMatches('...Session configuration object is not...',
                           self.browser.contents)
