## $Id: test_batching.py 7195 2011-11-25 07:34:07Z 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
##

# Tests for university related batching
import unittest

from zope.interface.verify import verifyClass, verifyObject
from waeup.sirp.interfaces import IBatchProcessor
from waeup.sirp.testing import FunctionalTestCase, FunctionalLayer
from waeup.sirp.university.batching import (
    FacultyProcessor, DepartmentProcessor, CourseProcessor,
    CertificateProcessor, CertificateCourseProcessor)
from waeup.sirp.university.certificate import Certificate, CertificateCourse
from waeup.sirp.university.course import Course
from waeup.sirp.university.department import Department


class TestFacultyProcessor(unittest.TestCase):

    def setUp(self):
        self.proc = FacultyProcessor()
        self.site1 = dict(faculties=dict())
        self.site2 = dict(faculties=dict(FAC='pseudo faculty'))
        self.row = dict(code='FAC')
        return

    def test_ifaces(self):
        # Make sure we fullfill all interface contracts
        verifyClass(IBatchProcessor, FacultyProcessor)
        verifyObject(IBatchProcessor, self.proc)
        return

    def test_get_entry(self):
        # if a faculty exists already, we will get it
        result1 = self.proc.getEntry(self.row, self.site1)
        result2 = self.proc.getEntry(self.row, self.site2)
        self.assertTrue(result1 is None)
        self.assertEqual(result2, 'pseudo faculty')
        return

    def test_del_entry(self):
        # make sure we can del entries.
        self.proc.delEntry(self.row, self.site2)
        self.assertTrue('FAC' not in self.site2.keys())
        return

class TestDepartmentProcessors(unittest.TestCase):

    def setUp(self):
        self.proc = DepartmentProcessor()
        self.site0 = dict()
        self.site1 = dict(faculties=dict())
        self.site2 = dict(faculties=dict(FAC=dict()))
        self.site3 = dict(faculties=dict(FAC=dict(DPT='pseudo department')))
        self.row = dict(code='DPT', faculty_code='FAC')
        return

    def test_ifaces(self):
        # Make sure we fullfill all interface contracts
        verifyClass(IBatchProcessor, DepartmentProcessor)
        verifyObject(IBatchProcessor, self.proc)
        return

    def test_parents_exist(self):
        # make sure we lookup parents correctly.
        result0 = self.proc.parentsExist(self.row, self.site0)
        result1 = self.proc.parentsExist(self.row, self.site1)
        result2 = self.proc.parentsExist(self.row, self.site2)
        result3 = self.proc.parentsExist(self.row, self.site3)
        self.assertTrue(result0 is False)
        self.assertTrue(result1 is False)
        self.assertTrue(result2 is True)
        self.assertTrue(result3 is True)
        return

    def test_entry_exists(self):
        # make sure we lookup entries correctly.
        result0 = self.proc.entryExists(self.row, dict())
        result1 = self.proc.entryExists(self.row, self.site1)
        result2 = self.proc.entryExists(self.row, self.site2)
        result3 = self.proc.entryExists(self.row, self.site3)
        self.assertTrue(result0 is False)
        self.assertTrue(result1 is False)
        self.assertTrue(result2 is False)
        self.assertTrue(result3 is True)
        return

    def test_get_entry(self):
        # we can get a dept. if it exists
        result1 = self.proc.getEntry(self.row, self.site2)
        result2 = self.proc.getEntry(self.row, self.site3)
        self.assertTrue(result1 is None)
        self.assertEqual(result2, 'pseudo department')
        return

    def test_del_entry(self):
        # we can delete departments
        self.proc.delEntry(self.row, self.site3)
        self.assertTrue('DPT' not in self.site3['faculties']['FAC'].keys())
        return

class CourseProcessorTests(FunctionalTestCase):

    layer = FunctionalLayer

    def setUp(self):
        super(CourseProcessorTests, self).setUp()
        self.proc = CourseProcessor()
        self.site0 = dict()
        self.site1 = dict(faculties=dict())
        self.site2 = dict(faculties=dict(FAC=dict()))
        self.department1 = Department(code='DPT')
        self.department2 = Department(code='DPT')
        self.course = Course(code='CRS')
        self.department2.courses['CRS'] = self.course
        self.site3 = dict(faculties=dict(FAC=dict(DPT=self.department1)))
        self.site4 = dict(faculties=dict(FAC=dict(DPT=self.department2)))
        self.row = dict(department_code='DPT', faculty_code='FAC', code="CRS")
        return

    def test_ifaces(self):
        # Make sure we fullfill all interface contracts
        verifyClass(IBatchProcessor, CourseProcessor)
        verifyObject(IBatchProcessor, self.proc)
        return

    def test_parents_exist(self):
        # make sure we lookup parents correctly
        result0 = self.proc.parentsExist(self.row, self.site0)
        result1 = self.proc.parentsExist(self.row, self.site1)
        result2 = self.proc.parentsExist(self.row, self.site2)
        result3 = self.proc.parentsExist(self.row, self.site3)
        result4 = self.proc.parentsExist(self.row, self.site4)
        self.assertTrue(result0 is False)
        self.assertTrue(result1 is False)
        self.assertTrue(result2 is False)
        self.assertTrue(result3 is True)
        self.assertTrue(result4 is True)
        return

    def test_entry_exists(self):
        # make sure we find an entry if it exists
        result0 = self.proc.entryExists(self.row, self.site0)
        result1 = self.proc.entryExists(self.row, self.site1)
        result2 = self.proc.entryExists(self.row, self.site2)
        result3 = self.proc.entryExists(self.row, self.site3)
        result4 = self.proc.entryExists(self.row, self.site4)
        self.assertTrue(result0 is False)
        self.assertTrue(result1 is False)
        self.assertTrue(result2 is False)
        self.assertTrue(result3 is False)
        self.assertTrue(result4 is True)
        return

    def test_get_entry(self):
        # make sure we can get an entry if it exists
        result1 = self.proc.getEntry(self.row, self.site3)
        result2 = self.proc.getEntry(self.row, self.site4)
        self.assertTrue(result1 is None)
        self.assertTrue(result2 is self.course)
        return

    def test_del_entry(self):
        # make sure we can delete entries
        self.assertTrue('CRS' in self.department2.courses.keys())
        self.proc.delEntry(self.row, self.site4)
        self.assertTrue('CRS' not in self.department2.courses.keys())
        return

class CertificateProcessorTests(FunctionalTestCase):

    layer = FunctionalLayer

    def setUp(self):
        super(CertificateProcessorTests, self).setUp()
        self.proc = CertificateProcessor()
        self.site0 = dict()
        self.site1 = dict(faculties=dict())
        self.site2 = dict(faculties=dict(FAC=dict()))
        self.department1 = Department(code='DPT')
        self.department2 = Department(code='DPT')
        self.certificate = Certificate(code='CRT')
        self.department2.certificates['CRT'] = self.certificate
        self.site3 = dict(faculties=dict(FAC=dict(DPT=self.department1)))
        self.site4 = dict(faculties=dict(FAC=dict(DPT=self.department2)))
        self.row = dict(department_code='DPT', faculty_code='FAC', code="CRT")
        return

    def test_ifaces(self):
        # Make sure we fullfill all interface contracts
        verifyClass(IBatchProcessor, CertificateProcessor)
        verifyObject(IBatchProcessor, self.proc)
        return

    def test_parents_exist(self):
        # make sure we can find all certificate parents
        result0 = self.proc.parentsExist(self.row, self.site0)
        result1 = self.proc.parentsExist(self.row, self.site1)
        result2 = self.proc.parentsExist(self.row, self.site2)
        result3 = self.proc.parentsExist(self.row, self.site3)
        result4 = self.proc.parentsExist(self.row, self.site4)
        self.assertTrue(result0 is False)
        self.assertTrue(result1 is False)
        self.assertTrue(result2 is False)
        self.assertTrue(result3 is True)
        self.assertTrue(result4 is True)
        return

    def test_entry_exists(self):
        # make sure we find an entry if it exists
        result0 = self.proc.entryExists(self.row, self.site0)
        result1 = self.proc.entryExists(self.row, self.site1)
        result2 = self.proc.entryExists(self.row, self.site2)
        result3 = self.proc.entryExists(self.row, self.site3)
        result4 = self.proc.entryExists(self.row, self.site4)
        self.assertTrue(result0 is False)
        self.assertTrue(result1 is False)
        self.assertTrue(result2 is False)
        self.assertTrue(result3 is False)
        self.assertTrue(result4 is True)
        return

    def test_get_entry(self):
        # make sure we can get an entry if it exists
        result1 = self.proc.getEntry(self.row, self.site3)
        result2 = self.proc.getEntry(self.row, self.site4)
        self.assertTrue(result1 is None)
        self.assertTrue(result2 is self.certificate)
        return

    def test_del_entry(self):
        # make sure we can delete entries
        self.assertTrue('CRT' in self.department2.certificates.keys())
        self.proc.delEntry(self.row, self.site4)
        self.assertTrue('CRT' not in self.department2.certificates.keys())
        return

class CertCourseProcessorTests(FunctionalTestCase):

    layer = FunctionalLayer

    def setUp(self):
        super(CertCourseProcessorTests, self).setUp()
        self.proc = CertificateCourseProcessor()
        self.site0 = dict()
        self.site1 = dict(faculties=dict())
        self.site2 = dict(faculties=dict(FAC=dict()))
        self.department1 = Department(code='DPT')
        self.department2 = Department(code='DPT')
        self.certificate = Certificate(code='CRT')
        self.department2.certificates['CRT'] = self.certificate
        self.course = Course(code='CRS')
        self.department2.certificates['CRT'].addCourseRef(self.course)
        self.cert_course = self.certificate['CRS_100']
        self.department2.courses['CRS'] = self.course
        self.site3 = dict(faculties=dict(FAC=dict(DPT=self.department1)))
        self.site4 = dict(faculties=dict(FAC=dict(DPT=self.department2)))
        self.row = dict(
            department_code='DPT',
            faculty_code='FAC',
            certificate_code='CRT',
            course=self.course, level='100',
            code='CRS_100')
        return

    def test_ifaces(self):
        # Make sure we fullfill all interface contracts
        verifyClass(IBatchProcessor, CertificateCourseProcessor)
        verifyObject(IBatchProcessor, self.proc)
        return

    def test_parents_exist(self):
        # make sure we can find all certificate parents
        result0 = self.proc.parentsExist(self.row, self.site0)
        result1 = self.proc.parentsExist(self.row, self.site1)
        result2 = self.proc.parentsExist(self.row, self.site2)
        result3 = self.proc.parentsExist(self.row, self.site3)
        result4 = self.proc.parentsExist(self.row, self.site4)
        self.assertTrue(result0 is False)
        self.assertTrue(result1 is False)
        self.assertTrue(result2 is False)
        self.assertTrue(result3 is False)
        self.assertTrue(result4 is True)
        return

    def test_entry_exists(self):
        # make sure we find an entry if it exists
        result0 = self.proc.entryExists(self.row, self.site0)
        result1 = self.proc.entryExists(self.row, self.site1)
        result2 = self.proc.entryExists(self.row, self.site2)
        result3 = self.proc.entryExists(self.row, self.site3)
        result4 = self.proc.entryExists(self.row, self.site4)
        self.assertTrue(result0 is False)
        self.assertTrue(result1 is False)
        self.assertTrue(result2 is False)
        self.assertTrue(result3 is False)
        self.assertTrue(result4 is True)
        return

    def test_get_entry(self):
        # make sure we can get an entry if it exists
        result1 = self.proc.getEntry(self.row, self.site3)
        result2 = self.proc.getEntry(self.row, self.site4)
        self.assertTrue(result1 is None)
        self.assertTrue(result2 is self.cert_course)
        return

    def test_del_entry(self):
        # make sure we can delete entries
        self.assertTrue('CRS_100' in self.certificate.keys())
        self.proc.delEntry(self.row, self.site4)
        self.assertTrue('CRS_100' not in self.certificate.keys())
        return
