## $Id: test_browser.py 13615 2016-01-14 14:41:20Z henrik $
##
## Copyright (C) 2013 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
##
"""
Test the applicant-related UI components.
"""
import os
from StringIO import StringIO
from datetime import datetime
from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
from zope.securitypolicy.interfaces import IPrincipalRoleManager
from waeup.kofa.browser.tests.test_pdf import samples_dir
from waeup.kofa.applicants.container import ApplicantsContainer
from waeup.uniben.testing import FunctionalLayer
from waeup.uniben.configuration import CustomSessionConfiguration
from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup, PH_LEN

class CustomApplicantUITests(ApplicantsFullSetup):
    # Tests for uploading/browsing the passport image of appplicants

    layer = FunctionalLayer

    #def setUp(self):
    #    super(CustomApplicantUITests, self).setUp()
    #    return

    def test_applicant_access(self):
        # Anonymous users can't see the application fee.
        self.browser.open(self.container_path)
        self.assertFalse('Application Fee' in self.browser.contents)
        # Applicants can edit their record
        self.browser.open(self.login_path)
        self.login()
        self.assertTrue(
            'You logged in.' in self.browser.contents)
        self.browser.open(self.edit_path)
        self.assertTrue(self.browser.url != self.login_path)
        self.assertEqual(self.browser.headers['Status'], '200 Ok')
        self.fill_correct_values()
        self.browser.getControl("Save").click()
        self.assertMatches('...Form has been saved...', self.browser.contents)
        # Applicants can't see the application fee.
        self.browser.open(self.container_path)
        self.assertFalse('Application Fee' in self.browser.contents)
        return
       
    def image_url(self, filename):
        return self.edit_path.replace('edit', filename)

    def test_upload_passport_wo_permission(self):
        # Create CRPU officer
        self.app['users'].addUser('mrcrpu', 'mrcrpusecret')
        self.app['users']['mrcrpu'].email = 'mrcrpu@foo.ng'
        self.app['users']['mrcrpu'].title = 'Carlo Pitter'
        prmglobal = IPrincipalRoleManager(self.app)
        prmglobal.assignRoleToPrincipal('waeup.CCOfficer', 'mrcrpu')
        # Login as CRPU officer
        self.browser.open(self.login_path)
        self.browser.getControl(name="form.login").value = 'mrcrpu'
        self.browser.getControl(name="form.password").value = 'mrcrpusecret'
        self.browser.getControl("Login").click()
        self.assertMatches('...You logged in...', self.browser.contents)
        # Let's try to change the passport image
        self.browser.open(self.manage_path)
        self.fill_correct_values()
        # Create a pseudo image file and select it to be uploaded in form
        pseudo_image = StringIO('I pretend to be a graphics file')
        ctrl = self.browser.getControl(name='form.passport')
        file_ctrl = ctrl.mech_control
        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
        self.browser.getControl("Save").click()
        self.assertMatches('...You are not entitled to upload passport pictures...',
            self.browser.contents)
        # The officer still sees the placeholder passport image
        self.browser.open(self.image_url('passport.jpg'))
        self.assertEqual(
            self.browser.headers['content-type'], 'image/jpeg')
        self.assertEqual(len(self.browser.contents), PH_LEN)
        # After adding the additional role ...
        prmglobal.assignRoleToPrincipal('waeup.PassportPictureManager', 'mrcrpu')
        # ... passport pictures can be uploaded
        self.browser.open(self.manage_path)
        self.fill_correct_values()
        pseudo_image = StringIO('I pretend to be a graphics file')
        ctrl = self.browser.getControl(name='form.passport')
        file_ctrl = ctrl.mech_control
        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
        self.browser.getControl("Save").click()
        self.assertMatches('...Form has been saved...', self.browser.contents)
        # There is a correct <img> link included
        self.assertTrue(
            '<img src="passport.jpg" height="180px" />' in self.browser.contents)
        # Browsing the link shows a real image
        self.browser.open(self.image_url('passport.jpg'))
        self.assertEqual(
            self.browser.headers['content-type'], 'image/jpeg')
        self.assertEqual(len(self.browser.contents), 31)

    def test_pay_admission_checking_fee(self):
        IWorkflowState(self.applicant).setState('admitted')
        self.applicant.screening_score = 55
        self.applicant.course_admitted = self.certificate
        self.login()
        # SessionConfiguration is not set, thus admission checking payment
        # is not necessary. Screening results and course admitted are visible.
        self.assertFalse(
            'Add admission checking payment ticket' in self.browser.contents)
        self.assertTrue('<a href="http://localhost/app/faculties/fac1/dep1/certificates/CERT1">CERT1 - Unnamed Certificate</a>' in self.browser.contents)
        self.assertTrue('<span>55</span>' in self.browser.contents)
        configuration = CustomSessionConfiguration()
        configuration.academic_session = datetime.now().year - 2
        self.app['configuration'].addSessionConfiguration(configuration)
        # Admission checking fee is 0, thus admission checking payment
        # is not necessary. Screening results and course admitted are visible.
        self.browser.open(self.view_path)
        self.assertFalse(
            'Add admission checking payment ticket' in self.browser.contents)
        self.assertTrue('<a href="http://localhost/app/faculties/fac1/dep1/certificates/CERT1">CERT1 - Unnamed Certificate</a>' in self.browser.contents)
        self.assertTrue('<span>55</span>' in self.browser.contents)
        configuration.admchecking_fee = 22.0
        # Admission checking payment button is now visible, but screening results
        # and course admitted are not.
        self.browser.open(self.view_path)
        self.assertTrue(
            'Add admission checking payment ticket' in self.browser.contents)
        self.assertFalse('<a href="http://localhost/app/faculties/fac1/dep1/certificates/CERT1">CERT1 - Unnamed Certificate</a>' in self.browser.contents)
        self.assertFalse('<span>55</span>' in self.browser.contents)
        # Application slip can't be downloaded
        self.assertFalse('Download application slip' in self.browser.contents)
        slip_path = self.view_path + '/application_slip.pdf'
        self.browser.open(slip_path)
        self.assertTrue(
            'Please pay admission checking fee before trying to download'
            in self.browser.contents)
        # Pay admission checking fee.
        self.browser.getControl("Add admission checking").click()
        p_id = self.applicant.keys()[0]
        self.applicant[p_id].p_state = 'paid'
        # Screening results and course admitted are visible after payment.
        self.browser.open(self.view_path)
        self.assertFalse(
            'Add admission checking payment ticket' in self.browser.contents)
        self.assertTrue('<a href="http://localhost/app/faculties/fac1/dep1/certificates/CERT1">CERT1 - Unnamed Certificate</a>' in self.browser.contents)
        self.assertTrue('<span>55</span>' in self.browser.contents)
        # Application slip can be downloaded again.
        self.browser.getLink("Download application slip").click()
        self.assertEqual(self.browser.headers['Status'], '200 Ok')
        self.assertEqual(self.browser.headers['Content-Type'],
                         'application/pdf')
        return

    def test_application_slip(self):

        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
        self.slip_path = self.view_path + '/application_slip.pdf'
        self.browser.open(self.manage_path)
        self.assertEqual(self.browser.headers['Status'], '200 Ok')
        self.fill_correct_values()
        self.browser.getControl("Save").click()
        IWorkflowState(self.applicant).setState('submitted')
        self.browser.open(self.manage_path)
        self.browser.getLink("Download application 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(), 'application_slip.pdf')
        open(path, 'wb').write(self.browser.contents)
        print "Sample application_slip.pdf written to %s" % path

    def test_akoka_application_slip(self):

        # Remove required FieldProperty attribute first ...
        delattr(ApplicantsContainer, 'prefix')
        # ... and replace by akoka
        self.applicantscontainer.prefix = 'afak'
        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
        self.slip_path = self.view_path + '/application_slip.pdf'
        self.browser.open(self.manage_path)
        self.assertEqual(self.browser.headers['Status'], '200 Ok')
        self.fill_correct_values()
        self.browser.getControl("Save").click()
        IWorkflowState(self.applicant).setState('submitted')
        self.browser.open(self.manage_path)
        self.browser.getLink("Download application 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(), 'akoka_application_slip.pdf')
        open(path, 'wb').write(self.browser.contents)
        print "Sample akoka_application_slip.pdf written to %s" % path

    def test_nils_application_slip(self):

        # Remove required FieldProperty attribute first ...
        #delattr(ApplicantsContainer, 'prefix')
        # ... and replace by akoka
        self.applicantscontainer.prefix = 'pgn'
        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
        self.slip_path = self.view_path + '/application_slip.pdf'
        self.browser.open(self.manage_path)
        self.assertEqual(self.browser.headers['Status'], '200 Ok')
        self.fill_correct_values()
        self.browser.getControl("Save").click()
        IWorkflowState(self.applicant).setState('submitted')
        self.browser.open(self.manage_path)
        self.browser.getLink("Download application 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(), 'nils_application_slip.pdf')
        open(path, 'wb').write(self.browser.contents)
        print "Sample nils_application_slip.pdf written to %s" % path
