Test bookings
=============

We want to test some browser views for Bookings.  We need some test
requests.  A request needs to be annotatable as we use memoize.

    >>> from zope.publisher.browser import TestRequest
    >>> from zope.annotation.interfaces import IAttributeAnnotatable
    >>> from zope.interface import classImplements
    >>> classImplements(TestRequest, IAttributeAnnotatable)
    >>> request = TestRequest()

At first there is only one Booking (as that is added by the
test/utils.py setup method).

    >>> len(self.catalog(portal_type='Booking'))
    1
    >>> from Products.eXtremeManagement.browser.bookings import BookingsDetailedView
    >>> bookview = BookingsDetailedView(self.portal, request)
    >>> len(bookview.bookinglist)
    1
    >>> bookview.bookinglist[0]['booking_hours']
    '3:15'
    >>> bookview.total
    '3:15'

Let's add a Booking as someone else.  That person should by default
only see his own Bookings.

    >>> self.login('employee')
    >>> self.task.invokeFactory('Booking', id='booking-emp', hours=2)
    'booking-emp'
    >>> bookview = BookingsDetailedView(self.portal, request)
    >>> len(bookview.bookinglist)
    1
    >>> bookview.bookinglist[0]['booking_hours']
    '2:00'
    >>> bookview.total
    '2:00'
    >>> len(self.catalog(portal_type='Booking'))
    2

Adding another one should update the total actual hours

    >>> self.task.invokeFactory('Booking', id='booking-emp-2', hours=3, minutes=30)
    'booking-emp-2'
    >>> bookview = BookingsDetailedView(self.portal, request)
    >>> len(bookview.bookinglist)
    2
    >>> bookview.total
    '5:30'

No bookings have been done in January 2007.

    >>> request = TestRequest(form={'year': 2007, 'month': 1})
    >>> bookview = BookingsDetailedView(self.portal, request)
    >>> bookview.bookinglist
    []
    >>> bookview.total
    '0:00'

Let us add one in that month.

    >>> from DateTime import DateTime
    >>> jan1 = DateTime('2007-01-01')
    >>> self.task.invokeFactory('Booking', id='emp-jan1', hours=1, bookingDate=jan1)
    'emp-jan1'

Since I have learned a few things about requests lately, let us check
it in three ways.

We first check it by adding some keyword arguments.

    >>> request = TestRequest()
    >>> bookview = BookingsDetailedView(self.portal, request, year=2007, month=1)
    >>> len(bookview.bookinglist)
    1
    >>> bookview.bookinglist[0]['booking_date'] in ('Jan 01, 2007', '2007-01-01')
    True

Then we check it by adding a dictionary

    >>> request = TestRequest()
    >>> options = dict(year=2007, month=1)
    >>> bookview = BookingsDetailedView(self.portal, request, **options)
    >>> len(bookview.bookinglist)
    1
    >>> bookview.bookinglist[0]['booking_date'] in ('Jan 01, 2007', '2007-01-01')
    True

And then we check it by adjusting the request, to show that the result
is the same.

    >>> request = TestRequest(form={'year': 2007, 'month': 1})
    >>> bookview = BookingsDetailedView(self.portal, request)
    >>> len(bookview.bookinglist)
    1
    >>> bookview.bookinglist[0]['booking_date'] in ('Jan 01, 2007', '2007-01-01')
    True

Now, a booking on the first of the month might inadvertently be listed
in the previous month as well.  Let's make sure we do not make that
mistake.

    >>> request = TestRequest(form={'year': 2006, 'month': 12})
    >>> bookview = BookingsDetailedView(self.portal, request)
    >>> bookview.bookinglist
    []


Daylight Savings Time can be annoying.  Bookings at Monday March 27
2006 can end up in overviews on Monday *and* Sunday.

    >>> request = TestRequest(form={'year': 2006, 'month': 3})
    >>> bookview = BookingsDetailedView(self.portal, request)
    >>> len(bookview.bookinglist)
    0
    >>> monday_after_dst = DateTime('2006-03-27')
    >>> self.task.invokeFactory('Booking', id='emp-mad06', hours=2, bookingDate=monday_after_dst)
    'emp-mad06'
    >>> request = TestRequest(form={'year': 2006, 'month': 3})
    >>> bookview = BookingsDetailedView(self.portal, request)
    >>> len(bookview.bookinglist)
    1

And in practice we noticed that it can apparantely also go wrong when
going from summer to winter time.  So we add a few bookings around
that time too.

In 2006 DST kicked in during the night of Saturday 28 October and
Sunday 29 October, at least in The Netherlands.

    >>> dummy = self.task.invokeFactory('Booking', id='emp-okt1', hours=1, bookingDate=DateTime('2006-10-01'))
    >>> dummy = self.task.invokeFactory('Booking', id='emp-okt28', hours=2, bookingDate=DateTime('2006-10-28'))
    >>> dummy = self.task.invokeFactory('Booking', id='emp-okt29', hours=3, bookingDate=DateTime('2006-10-29'))
    >>> dummy = self.task.invokeFactory('Booking', id='emp-okt30', hours=4, bookingDate=DateTime('2006-10-30'))
    >>> dummy = self.task.invokeFactory('Booking', id='emp-okt31', hours=5, bookingDate=DateTime('2006-10-31'))
    >>> dummy = self.task.invokeFactory('Booking', id='emp-nov1', hours=6, bookingDate=DateTime('2006-11-01'))
    >>> len(BookingsDetailedView(self.portal, TestRequest(form={'year': 2006, 'month': 10})).bookinglist)
    5
    >>> len(BookingsDetailedView(self.portal, TestRequest(form={'year': 2006, 'month': 11})).bookinglist)
    1

This does not show any errors though.  Which reminds us to test the
WeekBookingOverview and DayBookingOverview.  These can suffers from
DST bugs too if we are not careful.

First let's test some days.

    >>> from Products.eXtremeManagement.browser.bookings import DayBookingOverview
    >>> dayview = DayBookingOverview(self.portal, TestRequest())
    >>> dayview.total(date=DateTime(2006, 10, 27))
    '0:00'
    >>> dayview.total(date=DateTime(2006, 10, 28))
    '2:00'
    >>> dayview.total(date=DateTime(2006, 10, 29))
    '3:00'
    >>> dayview.total(date=DateTime(2006, 10, 30))
    '4:00'

Now we test the week view.

    >>> from Products.eXtremeManagement.browser.bookings import WeekBookingOverview
    >>> view = WeekBookingOverview(self.portal, TestRequest(form={'year': 2006, 'month': 10}))

Does it give the right totals for each week (and the correct amount of
weeks)?

    >>> [week['week_total'] for week in view.bookinglist]
    ['1:00', '0:00', '0:00', '0:00', '5:00', '15:00']
    >>> [week['week_number'] for week in view.bookinglist]
    [39, 40, 41, 42, 43, 44]

Let's look at week 4 of that month, at the end of which the DST kicks in.

    >>> week4 = view.bookinglist[4]
    >>> week4['week_start']
    'Oct 23, 2006'
    >>> week4['week_number']
    43
    >>> week4['days'][0]
    {'total': None, 'day_of_week': 'Monday'}
    >>> week4['days'][5]
    {'total': '2:00', 'day_of_week': 'Saturday'}
    >>> week4['days'][6]
    {'total': '3:00', 'day_of_week': 'Sunday'}

Let's also look at week 5.

    >>> view.bookinglist[5]['days'][0]
    {'total': '4:00', 'day_of_week': 'Monday'}
    >>> view.bookinglist[5]['days'][1]
    {'total': '5:00', 'day_of_week': 'Tuesday'}
    >>> view.bookinglist[5]['days'][2]
    {'total': '6:00', 'day_of_week': 'Wednesday'}
    >>> view.bookinglist[5]['days'][3]
    {'total': None, 'day_of_week': 'Thursday'}

At the beginning of the year things can go wrong, so test that too.

    >>> jan1 = DateTime('2002-01-01')
    >>> self.task.invokeFactory('Booking', id='jan102', hours=1, bookingDate=jan1)
    'jan102'
    >>> view = WeekBookingOverview(self.portal, TestRequest(form={'year': 2002, 'month': 1}))
    >>> [week['week_total'] for week in view.bookinglist]
    ['1:00', '0:00', '0:00', '0:00', '0:00']
