#
# Tests for date_components_support.py
#

from Products.CMFPlone.tests import PloneTestCase

from DateTime import DateTime

def sortTuple(t):
    l = list(t)
    l.sort()
    return tuple(l)


class TestDateComponentsSupport(PloneTestCase.PloneTestCase):

    def afterSetUp(self):
        date = DateTime(2002, 8, 1, 17, 42, 0)
        self.d = self.portal.date_components_support(date)

    def testElements(self):
        self.assertEqual(sortTuple(self.d.keys()), 
                ('ampm', 'days', 'hours', 'minutes', 'months', 'years'))

    def testYears(self):
        this_year = DateTime().year()
        site_properties = self.portal.portal_properties.site_properties
        min_year = site_properties.getProperty('calendar_starting_year', 1999)
        max_year = site_properties.getProperty('calendar_future_years_available', 5) + this_year

        data = [
            {'selected': None, 'id': '--', 'value': '0000'}
        ]

        for y in range(min_year, max_year+1):
            d = {'selected': None, 'id': y, 'value': y}
            if y == 2002:
                d['selected'] = 1
            data.append(d)

        years = self.d.get('years')
        for i in range(max_year - min_year + 1):
            self.assertEqual(years[i], data[i])

    def testMonths(self):
        data = [
            {'selected': None, 'id': '--',      'value': '00'},
            {'selected': None, 'id': 'January',   'value': '01'},
            {'selected': None, 'id': 'February',  'value': '02'},
            {'selected': None, 'id': 'March',     'value': '03'},
            {'selected': None, 'id': 'April',     'value': '04'},
            {'selected': None, 'id': 'May',       'value': '05'},
            {'selected': None, 'id': 'June',      'value': '06'},
            {'selected': None, 'id': 'July',      'value': '07'},
            {'selected': 1,    'id': 'August',    'value': '08'},
            {'selected': None, 'id': 'September', 'value': '09'},
            {'selected': None, 'id': 'October',   'value': '10'},
            {'selected': None, 'id': 'November',  'value': '11'},
            {'selected': None, 'id': 'December',  'value': '12'},
        ]

        months = self.d.get('months')
        for i in range(13):
            self.assertEqual(months[i], data[i])

    def testDays(self):
        data = [
            {'selected': None, 'id': '--', 'value': '00'},
            {'selected': 1,    'id': 1,      'value': '01'},
            {'selected': None, 'id': 2,      'value': '02'},
            {'selected': None, 'id': 3,      'value': '03'},
            {'selected': None, 'id': 4,      'value': '04'},
            {'selected': None, 'id': 5,      'value': '05'},
            {'selected': None, 'id': 6,      'value': '06'},
            {'selected': None, 'id': 7,      'value': '07'},
            {'selected': None, 'id': 8,      'value': '08'},
            {'selected': None, 'id': 9,      'value': '09'},
            {'selected': None, 'id': 10,     'value': '10'},
            {'selected': None, 'id': 11,     'value': '11'},
            {'selected': None, 'id': 12,     'value': '12'},
            {'selected': None, 'id': 13,     'value': '13'},
            {'selected': None, 'id': 14,     'value': '14'},
            {'selected': None, 'id': 15,     'value': '15'},
            {'selected': None, 'id': 16,     'value': '16'},
            {'selected': None, 'id': 17,     'value': '17'},
            {'selected': None, 'id': 18,     'value': '18'},
            {'selected': None, 'id': 19,     'value': '19'},
            {'selected': None, 'id': 20,     'value': '20'},
            {'selected': None, 'id': 21,     'value': '21'},
            {'selected': None, 'id': 22,     'value': '22'},
            {'selected': None, 'id': 23,     'value': '23'},
            {'selected': None, 'id': 24,     'value': '24'},
            {'selected': None, 'id': 25,     'value': '25'},
            {'selected': None, 'id': 26,     'value': '26'},
            {'selected': None, 'id': 27,     'value': '27'},
            {'selected': None, 'id': 28,     'value': '28'},
            {'selected': None, 'id': 29,     'value': '29'},
            {'selected': None, 'id': 30,     'value': '30'},
            {'selected': None, 'id': 31,     'value': '31'},
        ]
    
        days = self.d.get('days')
        for i in range(32):
            self.assertEqual(days[i], data[i])

    def testHours(self):
        data = [
            {'selected': None, 'id': '--', 'value': '00'},
            {'selected': None, 'id': '00',   'value': '00'},
            {'selected': None, 'id': '01',   'value': '01'},
            {'selected': None, 'id': '02',   'value': '02'},
            {'selected': None, 'id': '03',   'value': '03'},
            {'selected': None, 'id': '04',   'value': '04'},
            {'selected': None, 'id': '05',   'value': '05'},
            {'selected': None, 'id': '06',   'value': '06'},
            {'selected': None, 'id': '07',   'value': '07'},
            {'selected': None, 'id': '08',   'value': '08'},
            {'selected': None, 'id': '09',   'value': '09'},
            {'selected': None, 'id': '10',   'value': '10'},
            {'selected': None, 'id': '11',   'value': '11'},
            {'selected': None, 'id': '12',   'value': '12'},
            {'selected': None, 'id': '13',   'value': '13'},
            {'selected': None, 'id': '14',   'value': '14'},
            {'selected': None, 'id': '15',   'value': '15'},
            {'selected': None, 'id': '16',   'value': '16'},
            {'selected': 1,    'id': '17',   'value': '17'},
            {'selected': None, 'id': '18',   'value': '18'},
            {'selected': None, 'id': '19',   'value': '19'},
            {'selected': None, 'id': '20',   'value': '20'},
            {'selected': None, 'id': '21',   'value': '21'},
            {'selected': None, 'id': '22',   'value': '22'},
            {'selected': None, 'id': '23',   'value': '23'},
        ]

        hours = self.d.get('hours')
        for i in range(25):
            self.assertEqual(hours[i], data[i])

    def testMinutes(self):
        data = [
            {'selected': None, 'id': '--', 'value': '00'},
            {'selected': None, 'id': '00',   'value': '00'},
            {'selected': None, 'id': '05',   'value': '05'},
            {'selected': None, 'id': '10',   'value': '10'},
            {'selected': None, 'id': '15',   'value': '15'},
            {'selected': None, 'id': '20',   'value': '20'},
            {'selected': None, 'id': '25',   'value': '25'},
            {'selected': None, 'id': '30',   'value': '30'},
            {'selected': None, 'id': '35',   'value': '35'},
            {'selected': None, 'id': '40',   'value': '40'},
            {'selected': 1,    'id': '45',   'value': '45'},
            {'selected': None, 'id': '50',   'value': '50'},
            {'selected': None, 'id': '55',   'value': '55'},
        ]

        minutes = self.d.get('minutes')
        for i in range(13):
            self.assertEqual(minutes[i], data[i])

    def testAM(self):
        d = DateTime(2002, 8, 1, 3, 0, 0)
        d = self.portal.date_components_support(d)
        self.assertEqual(d.get('ampm'), [])

    def testPM(self):
        ampm = self.d.get('ampm')
        self.assertEqual(ampm, [])


class TestDateComponentsSupportDefault(PloneTestCase.PloneTestCase):

    def afterSetUp(self):
        self.d = self.portal.date_components_support(None)

    def testElements(self):
        self.assertEqual(sortTuple(self.d.keys()), 
                ('ampm', 'days', 'hours', 'minutes', 'months', 'years'))

    def testYears(self):
        this_year = DateTime().year()
        site_properties = self.portal.portal_properties.site_properties
        min_year = site_properties.getProperty('calendar_starting_year', 1999)
        max_year = site_properties.getProperty('calendar_future_years_available', 5) + this_year

        data = [
            {'selected': None, 'id': '--', 'value': '0000'}
        ]

        for y in range(min_year, max_year+1):
            d = {'selected': None, 'id': y, 'value': y}
            if y == this_year:
                d['selected'] = 1
            data.append(d)

        years = self.d.get('years')
        for i in range(max_year - min_year + 1):
            self.assertEqual(years[i], data[i])

    def testMonths(self):
        data = [
            {'selected': 1,    'id': '--',      'value': '00'},
            {'selected': None, 'id': 'January',   'value': '01'},
            {'selected': None, 'id': 'February',  'value': '02'},
            {'selected': None, 'id': 'March',     'value': '03'},
            {'selected': None, 'id': 'April',     'value': '04'},
            {'selected': None, 'id': 'May',       'value': '05'},
            {'selected': None, 'id': 'June',      'value': '06'},
            {'selected': None, 'id': 'July',      'value': '07'},
            {'selected': None, 'id': 'August',    'value': '08'},
            {'selected': None, 'id': 'September', 'value': '09'},
            {'selected': None, 'id': 'October',   'value': '10'},
            {'selected': None, 'id': 'November',  'value': '11'},
            {'selected': None, 'id': 'December',  'value': '12'},
        ]

        months = self.d.get('months')
        for i in range(13):
            self.assertEqual(months[i], data[i])

    def testDays(self):
        data = [
            {'selected': 1,    'id': '--', 'value': '00'},
            {'selected': None, 'id': 1,      'value': '01'},
            {'selected': None, 'id': 2,      'value': '02'},
            {'selected': None, 'id': 3,      'value': '03'},
            {'selected': None, 'id': 4,      'value': '04'},
            {'selected': None, 'id': 5,      'value': '05'},
            {'selected': None, 'id': 6,      'value': '06'},
            {'selected': None, 'id': 7,      'value': '07'},
            {'selected': None, 'id': 8,      'value': '08'},
            {'selected': None, 'id': 9,      'value': '09'},
            {'selected': None, 'id': 10,     'value': '10'},
            {'selected': None, 'id': 11,     'value': '11'},
            {'selected': None, 'id': 12,     'value': '12'},
            {'selected': None, 'id': 13,     'value': '13'},
            {'selected': None, 'id': 14,     'value': '14'},
            {'selected': None, 'id': 15,     'value': '15'},
            {'selected': None, 'id': 16,     'value': '16'},
            {'selected': None, 'id': 17,     'value': '17'},
            {'selected': None, 'id': 18,     'value': '18'},
            {'selected': None, 'id': 19,     'value': '19'},
            {'selected': None, 'id': 20,     'value': '20'},
            {'selected': None, 'id': 21,     'value': '21'},
            {'selected': None, 'id': 22,     'value': '22'},
            {'selected': None, 'id': 23,     'value': '23'},
            {'selected': None, 'id': 24,     'value': '24'},
            {'selected': None, 'id': 25,     'value': '25'},
            {'selected': None, 'id': 26,     'value': '26'},
            {'selected': None, 'id': 27,     'value': '27'},
            {'selected': None, 'id': 28,     'value': '28'},
            {'selected': None, 'id': 29,     'value': '29'},
            {'selected': None, 'id': 30,     'value': '30'},
            {'selected': None, 'id': 31,     'value': '31'},
        ]
    
        days = self.d.get('days')
        for i in range(32):
            self.assertEqual(days[i], data[i])

    def testHours(self):
        data = [
            {'selected': 1,    'id': '--', 'value': '00'},
            {'selected': None, 'id': '00',   'value': '00'},
            {'selected': None, 'id': '01',   'value': '01'},
            {'selected': None, 'id': '02',   'value': '02'},
            {'selected': None, 'id': '03',   'value': '03'},
            {'selected': None, 'id': '04',   'value': '04'},
            {'selected': None, 'id': '05',   'value': '05'},
            {'selected': None, 'id': '06',   'value': '06'},
            {'selected': None, 'id': '07',   'value': '07'},
            {'selected': None, 'id': '08',   'value': '08'},
            {'selected': None, 'id': '09',   'value': '09'},
            {'selected': None, 'id': '10',   'value': '10'},
            {'selected': None, 'id': '11',   'value': '11'},
            {'selected': None, 'id': '12',   'value': '12'},
            {'selected': None, 'id': '13',   'value': '13'},
            {'selected': None, 'id': '14',   'value': '14'},
            {'selected': None, 'id': '15',   'value': '15'},
            {'selected': None, 'id': '16',   'value': '16'},
            {'selected': None, 'id': '17',   'value': '17'},
            {'selected': None, 'id': '18',   'value': '18'},
            {'selected': None, 'id': '19',   'value': '19'},
            {'selected': None, 'id': '20',   'value': '20'},
            {'selected': None, 'id': '21',   'value': '21'},
            {'selected': None, 'id': '22',   'value': '22'},
            {'selected': None, 'id': '23',   'value': '23'},
        ]

        hours = self.d.get('hours')
        for i in range(25):
            self.assertEqual(hours[i], data[i])

    def testMinutes(self):
        data = [
            {'selected': 1,    'id': '--', 'value': '00'},
            {'selected': None, 'id': '00',   'value': '00'},
            {'selected': None, 'id': '05',   'value': '05'},
            {'selected': None, 'id': '10',   'value': '10'},
            {'selected': None, 'id': '15',   'value': '15'},
            {'selected': None, 'id': '20',   'value': '20'},
            {'selected': None, 'id': '25',   'value': '25'},
            {'selected': None, 'id': '30',   'value': '30'},
            {'selected': None, 'id': '35',   'value': '35'},
            {'selected': None, 'id': '40',   'value': '40'},
            {'selected': None, 'id': '45',   'value': '45'},
            {'selected': None, 'id': '50',   'value': '50'},
            {'selected': None, 'id': '55',   'value': '55'},
        ]

        minutes = self.d.get('minutes')
        for i in range(13):
            self.assertEqual(minutes[i], data[i])

    def testAMPM(self):
        ampm = self.d.get('ampm')
        self.assertEqual(ampm, [])


class TestDateComponentsSupportAMPM(PloneTestCase.PloneTestCase):

    def afterSetUp(self):
        date = DateTime(2002, 8, 1, 17, 42, 0)
        self.d = self.portal.date_components_support(date, use_ampm=1)

    def testElements(self):
        self.assertEqual(sortTuple(self.d.keys()),
                ('ampm', 'days', 'hours', 'minutes', 'months', 'years'))

    def testHours(self):
        data = [
            {'selected': None, 'id': '--', 'value': '12'},
            {'selected': None, 'id': '12',   'value': '12'},
            {'selected': None, 'id': '01',   'value': '01'},
            {'selected': None, 'id': '02',   'value': '02'},
            {'selected': None, 'id': '03',   'value': '03'},
            {'selected': None, 'id': '04',   'value': '04'},
            {'selected': 1,    'id': '05',   'value': '05'},
            {'selected': None, 'id': '06',   'value': '06'},
            {'selected': None, 'id': '07',   'value': '07'},
            {'selected': None, 'id': '08',   'value': '08'},
            {'selected': None, 'id': '09',   'value': '09'},
            {'selected': None, 'id': '10',   'value': '10'},
            {'selected': None, 'id': '11',   'value': '11'},
        ]

        hours = self.d.get('hours')
        for i in range(13):
            self.assertEqual(hours[i], data[i])

    def testAM(self):
        d = DateTime(2002, 8, 1, 3, 0, 0)
        d = self.portal.date_components_support(d, use_ampm=1)

        data = [
            {'selected': None, 'id': '--', 'value': 'AM'},
            {'selected': 1,    'id': 'AM',   'value': 'AM'},
            {'selected': None, 'id': 'PM',   'value': 'PM'},
        ]

        ampm = d.get('ampm')
        for i in range(3):
            self.assertEqual(ampm[i], data[i])

    def testPM(self):
        data = [
            {'selected': None, 'id': '--', 'value': 'AM'},
            {'selected': None, 'id': 'AM',   'value': 'AM'},
            {'selected': 1,    'id': 'PM',   'value': 'PM'},
        ]

        ampm = self.d.get('ampm')
        for i in range(3):
            self.assertEqual(ampm[i], data[i])


class TestDateComponentsSupportAMPMDefault(PloneTestCase.PloneTestCase):

    def afterSetUp(self):
        self.d = self.portal.date_components_support(None, use_ampm=1)

    def testElements(self):
        self.assertEqual(sortTuple(self.d.keys()),
                ('ampm', 'days', 'hours', 'minutes', 'months', 'years'))

    def testHours(self):
        data = [
            {'selected': 1,    'id': '--', 'value': '12'},
            {'selected': None, 'id': '12',   'value': '12'},
            {'selected': None, 'id': '01',   'value': '01'},
            {'selected': None, 'id': '02',   'value': '02'},
            {'selected': None, 'id': '03',   'value': '03'},
            {'selected': None, 'id': '04',   'value': '04'},
            {'selected': None, 'id': '05',   'value': '05'},
            {'selected': None, 'id': '06',   'value': '06'},
            {'selected': None, 'id': '07',   'value': '07'},
            {'selected': None, 'id': '08',   'value': '08'},
            {'selected': None, 'id': '09',   'value': '09'},
            {'selected': None, 'id': '10',   'value': '10'},
            {'selected': None, 'id': '11',   'value': '11'},
        ]

        hours = self.d.get('hours')
        for i in range(13):
            self.assertEqual(hours[i], data[i])

    def testAMPM(self):
        data = [
            {'selected': 1,    'id': '--', 'value': 'AM'},
            {'selected': None, 'id': 'AM',   'value': 'AM'},
            {'selected': None, 'id': 'PM',   'value': 'PM'},
        ]

        ampm = self.d.get('ampm')
        for i in range(2):
            self.assertEqual(ampm[i], data[i])


class TestDateComponentsSupportMinuteStepDefault(PloneTestCase.PloneTestCase):

    def testMinutesStep1(self):
        data = [
            {'selected': 1,    'id': '--', 'value': '00'},
        ]
        for x in range(0, 60, 1):
            d={'id': '%02d' % x, 'value': '%02d' % x, 'selected': None}
            data.append(d)

        d = self.portal.date_components_support(None, minute_step=1)
        minutes = d.get('minutes')
        for i in range(61):
            self.assertEqual(minutes[i], data[i])

    def testMinutesStep10(self):
        data = [
            {'selected': 1,    'id': '--', 'value': '00'},
        ]
        for x in range(0, 60, 10):
            d={'id': '%02d' % x, 'value': '%02d' % x, 'selected': None}
            data.append(d)

        d = self.portal.date_components_support(None, minute_step=10)
        minutes = d.get('minutes')
        for i in range(7):
            self.assertEqual(minutes[i], data[i])


class TestSpecialCases(PloneTestCase.PloneTestCase):

    def testNoneUsesDefault(self):
        d = self.portal.date_components_support(None)
        hours = d.get('hours')
        # default == 1
        self.failUnless(hours[0]['selected'])

    def testEmptyStringUsesDefault(self):
        d = self.portal.date_components_support('')
        hours = d.get('hours')
        # default == 1
        self.failUnless(hours[0]['selected'])

    def testDateWithGMT(self):
        # Any GMT suffix gets truncated
        d = self.portal.date_components_support('2004/08/31 04:30:00 GMT+2')
        hours = d.get('hours')
        # default == 0
        self.failUnless(hours[5]['selected'])   # 4th hour

    def testDateOnly(self):
        d = self.portal.date_components_support('2004/08/31')
        hours = d.get('hours')
        # default == 0
        self.failUnless(hours[1]['selected'])   # 0th hour

    def testInvalidDateWithGMT(self):
        # Any GMT suffix gets truncated
        d = self.portal.date_components_support('2004/02/31 00:30:00 GMT+2')
        hours = d.get('hours')
        # default == 1
        self.failUnless(hours[0]['selected'])

    def testInvalidDateOnly(self):
        d = self.portal.date_components_support('2004/02/31')
        hours = d.get('hours')
        # default == 1
        self.failUnless(hours[0]['selected'])


def test_suite():
    from unittest import TestSuite, makeSuite
    suite = TestSuite()
    suite.addTest(makeSuite(TestDateComponentsSupport))
    suite.addTest(makeSuite(TestDateComponentsSupportDefault))
    suite.addTest(makeSuite(TestDateComponentsSupportAMPM))
    suite.addTest(makeSuite(TestDateComponentsSupportAMPMDefault))
    suite.addTest(makeSuite(TestDateComponentsSupportMinuteStepDefault))
    suite.addTest(makeSuite(TestSpecialCases))
    return suite
