Functional doctest for SchoolTool Journal Attendance
====================================================

Let's log in with the manager account:

    >>> from schooltool.lyceum.journal.ftests import printGradebookTable
    >>> manager = Browser('manager', 'schooltool')

Set up a basic school year:

    >>> manager.getLink('Manage').click()
    >>> manager.getLink('School Years').click()
    >>> manager.getLink('New School Year').click()
    >>> manager.getControl('Title').value = '2005'
    >>> manager.getControl('First day').value = '2005-09-01'
    >>> manager.getControl('Last day').value = '2006-07-31'
    >>> manager.getControl('Add').click()

Add some teachers:

    >>> from schooltool.basicperson.browser.ftests.setup import addPerson
    >>> addPerson('Pete', 'Teacher', username='pete', password='pwd', groups=['teachers'])

A class:

    >>> manager.getLink('2005').click()
    >>> manager.getLink('Groups').click()
    >>> manager.getLink('New Group').click()
    >>> manager.getControl('Title').value = "2a"
    >>> manager.getControl('Add').click()

And some students:

    >>> addPerson('Frum', 'Student', username='frum', password='pwd', groups=['students', '2a'])
    >>> addPerson('Grum', 'Student', username='grum', password='pwd', groups=['students', '2a'])

Add a term:

    >>> manager.getLink('2005').click()
    >>> manager.getLink('Add a new term').click()
    >>> manager.getControl('Title').value = '2005 Fall 1'
    >>> manager.getControl('Start date').value = '2005-09-01'
    >>> manager.getControl('End date').value = '2005-10-31'
    >>> manager.getControl('Next').click()
    >>> manager.getControl('Saturday').click()
    >>> manager.getControl('Sunday').click()
    >>> manager.getControl('Add term').click()

Timetable schema:

    >>> manager.getLink('2005').click()
    >>> manager.getLink('School Timetables').click()
    >>> manager.getLink('New Timetable').click()

    >>> manager.getControl('Next').click()
    >>> manager.getControl('Days of the week').click()
    >>> manager.getControl('Same time each day').click()
    >>> manager.getControl(name='field.times').value = '9:00-10:00\n10:30-11:30'
    >>> manager.getControl('Next').click()
    >>> manager.getControl('Have names').click()
    >>> manager.getControl(name='field.periods').value = 'A\nB'
    >>> manager.getControl('Next').click()
    >>> manager.getControl('Same').click()
    >>> manager.getControl('Next').click()
    >>> manager.getControl('No').click()

A couple of sections:

    >>> from schooltool.app.browser.ftests.setup import addSection
    >>> from schooltool.app.browser.ftests.setup import addCourse
    >>> addCourse("History", "2005")

    >>> addSection("History", "2005", "2005 Fall 1",
    ...            title="History (1a)",
    ...            instructors=['Pete'],
    ...            members=['Grum', 'Frum'])

    >>> addSection("History", "2005", "2005 Fall 1",
    ...            title="History (1a)",
    ...            instructors=['Pete'],
    ...            members=['Grum', 'Frum'])

Let's schedule the sections:

    >>> manager.getLink('2005').click()
    >>> manager.getLink('2005 Fall 1').click()
    >>> manager.getLink('Sections').click()
    >>> manager.getLink(url='sections/1').click()
    >>> manager.getLink('Schedule').click()
    >>> manager.getLink('Add Timetable').click()
    >>> manager.getControl('Add').click()
    >>> manager.getControl(name='period.1-.Period-').value = True
    >>> manager.getControl(name='period.1-.Period-2-').value = True
    >>> manager.getControl(name='period.2-.Period-').value = True
    >>> manager.getControl('Save').click()

Let's log in with the teacher account:

    >>> teacher = Browser()
    >>> teacher.handleErrors = False
    >>> teacher.open('http://localhost/')
    >>> teacher.getLink('Log In').click()
    >>> teacher.getControl('Username').value = 'pete'
    >>> teacher.getControl('Password').value = 'pwd'
    >>> teacher.getControl('Log in').click()

Let's mark Frum as if he has skipped some lessons:

    >>> teacher.open('http://localhost/persons/frum/calendar/2005-09-06')
    >>> teacher.getLink('Journal', index=1).click()
    >>> teacher.getLink('Frum').click()
    >>> printGradebookTable(teacher.contents)
    +-----+------------+-----------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+---------+---------+
    | Nr. | First Name | Last Name | 06      | 06 B    | 07 A    | 13 A    | 13 B    | 14 A    | 20 A    | 20 B    | 21 A    | 27 A    | 27 B    | 28 A    | Average | Absences | Tardies | Excused |
    +-----+------------+-----------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+---------+---------+
    | 1   | Frum       | Student   | [_____] | [_____] | [_____] | [_____] | [_____] | [_____] | [_____] | [_____] | [_____] | [_____] | [_____] | [_____] |         |          |         |         |
    | 2   | Grum       | Student   | [_____] |         |         |         |         |         |         |         |         |         |         |         |         |          |         |         |
    +-----+------------+-----------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+---------+---------+

    >>> cells = analyze.queryHTML('//table[@class="data"]//input[@type="text"]/@name', teacher.contents)
    >>> for i in range(8):
    ...     teacher.getControl(name=cells[i]).value = 'a'
    >>> teacher.getControl('Update').click()
    >>> printGradebookTable(teacher.contents)
    +-----+------------+-----------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+---------+---------+
    | Nr. | First Name | Last Name | 06      | 06 B    | 07 A    | 13 A    | 13 B    | 14 A    | 20 A    | 20 B    | 21 A    | 27 A    | 27 B    | 28 A    | Average | Absences | Tardies | Excused |
    +-----+------------+-----------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+---------+---------+
    | 1   | Frum       | Student   | [a____] | [a____] | [a____] | [a____] | [a____] | [a____] | [a____] | [a____] | [_____] | [_____] | [_____] | [_____] |         | 8        |         | 8 / 0   |
    | 2   | Grum       | Student   | [_____] |         |         |         |         |         |         |         |         |         |         |         |         |          |         |         |
    +-----+------------+-----------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+---------+---------+

    >>> teacher.getLink('07').click()
    >>> printGradebookTable(teacher.contents)
    +-----+------------+-----------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+---------+---------+
    | Nr. | First Name | Last Name | 06 A    | 06 B    | 07      | 13 A    | 13 B    | 14 A    | 20 A    | 20 B    | 21 A    | 27 A    | 27 B    | 28 A    | Average | Absences | Tardies | Excused |
    +-----+------------+-----------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+---------+---------+
    | 1   | Frum       | Student   | [a____] | [a____] | [a____] | [a____] | [a____] | [a____] | [a____] | [a____] | [_____] | [_____] | [_____] | [_____] |         | 8        |         | 8 / 0   |
    | 2   | Grum       | Student   |         |         | [_____] |         |         |         |         |         |         |         |         |         |         |          |         |         |
    +-----+------------+-----------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+---------+---------+

    >>> manager.open('http://localhost/schoolyears/2005/groups/2a/attendance.html')
    >>> manager.getLink('September').click()
    >>> printGradebookTable(manager.contents)
    +------------+-----------+----+----+----+----+----+----+----+----+-------+
    | First Name | Last Name | 06 | 07 | 13 | 14 | 20 | 21 | 27 | 28 | Total |
    +------------+-----------+----+----+----+----+----+----+----+----+-------+
    | Frum       | Student   | 2  | 1  | 2  | 1  | 2  |    |    |    | 8     |
    | Grum       | Student   |    |    |    |    |    |    |    |    |       |
    +------------+-----------+----+----+----+----+----+----+----+----+-------+

    >>> manager.getLink('Frum').click()
    >>> printGradebookTable(manager.contents)
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+
    | First Name | Last Name | 06  | 07  | 13  | 14  | 20  | 21 | 27 | 28 | Total |
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+
    | Frum       | Student   | 2   | 1   | 2   | 1   | 2   |    |    |    | 8     |
    ...
    | Grum       | Student   |     |     |     |     |     |    |    |    |       |
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+

    XXX: Explaining absences not yet implemented, expected result is:
    | Explained: |           | [ ] | [ ] | [ ] | [ ] | [ ] |    |    |    |       |

    >>> cells = analyze.queryHTML('//table[@class="data"]//input[@type="checkbox"]/@name', manager.contents)
    >>> manager.getControl(name=cells[0]).value = ["checked"]
    >>> manager.getControl(name=cells[2]).value = ["checked"]
    >>> manager.getControl('Update').click()
    >>> printGradebookTable(manager.contents)
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+
    | First Name | Last Name | 06  | 07  | 13  | 14  | 20  | 21 | 27 | 28 | Total |
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+
    | Frum       | Student   | 2   | 1   | 2   | 1   | 2   |    |    |    | 8     |
    ...
    | Grum       | Student   |     |     |     |     |     |    |    |    |       |
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+

    XXX: Explaining absences not yet implemented, expected result is:
    | Explained: |           | [V] | [ ] | [V] | [ ] | [ ] |    |    |    |       |

    >>> manager.getLink('13').click()

    >>> printGradebookTable(manager.contents)
    +------------+-----------+-----+-----+
    | First Name | Last Name | A   | B   |
    +------------+-----------+-----+-----+
    | Frum       | Student   | n   | n   |
    | Explained: |           | [V] | [V] |
    | Grum       | Student   |     |     |
    +------------+-----------+-----+-----+

    >>> cells = analyze.queryHTML('//table[@class="data"]//input[@type="checkbox"]/@name', manager.contents)
    >>> manager.getControl(name=cells[1]).value = ["checked"]
    >>> manager.getControl('Update').click()
    >>> printGradebookTable(manager.contents)
    +------------+-----------+-----+-----+
    | First Name | Last Name | A   | B   |
    +------------+-----------+-----+-----+
    | Frum       | Student   | n   | n   |
    | Explained: |           | [V] | [V] |
    | Grum       | Student   |     |     |
    +------------+-----------+-----+-----+

    >>> manager.getLink('Show the whole month').click()
    >>> printGradebookTable(manager.contents)
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+
    | First Name | Last Name | 06  | 07  | 13  | 14  | 20  | 21 | 27 | 28 | Total |
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+
    | Frum       | Student   | 2   | 1   | 2   | 1   | 2   |    |    |    | 8     |
    ...
    | Grum       | Student   |     |     |     |     |     |    |    |    |       |
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+
    
    XXX: Explaining absences not yet implemented, expected result is:
    | Explained: |           | [V] | [ ] | [V] | [ ] | [ ] |    |    |    |       |

    >>> cells = analyze.queryHTML('//table[@class="data"]//input[@type="checkbox"]/@name', manager.contents)
    >>> manager.getControl(name=cells[0]).value = []
    >>> manager.getControl('Update').click()
    >>> printGradebookTable(manager.contents)
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+
    | First Name | Last Name | 06  | 07  | 13  | 14  | 20  | 21 | 27 | 28 | Total |
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+
    | Frum       | Student   | 2   | 1   | 2   | 1   | 2   |    |    |    | 8     |
    ...
    | Grum       | Student   |     |     |     |     |     |    |    |    |       |
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+

    XXX: Explaining absences not yet implemented, expected result is:
    | Explained: |           | [ ] | [ ] | [V] | [ ] | [ ] |    |    |    |       |

    >>> manager.getLink('13').click()
    >>> printGradebookTable(manager.contents)
    +------------+-----------+-----+-----+
    | First Name | Last Name | A   | B   |
    +------------+-----------+-----+-----+
    | Frum       | Student   | n   | n   |
    ...
    | Grum       | Student   |     |     |
    +------------+-----------+-----+-----+

    XXX: Explaining absences not yet implemented, expected result is:
    | Explained: |           | [V] | [V] |

    >>> cells = analyze.queryHTML('//table[@class="data"]//input[@type="checkbox"]/@name', manager.contents)
    >>> manager.getControl(name=cells[0]).value = ["checked"]
    >>> manager.getControl(name=cells[1]).value = []
    >>> manager.getControl('Update').click()
    >>> printGradebookTable(manager.contents)
    +------------+-----------+-----+-----+
    | First Name | Last Name | A   | B   |
    +------------+-----------+-----+-----+
    | Frum       | Student   | n   | n   |
    ...
    | Grum       | Student   |     |     |
    +------------+-----------+-----+-----+

    XXX: Explaining absences not yet implemented, expected result is:
    | Explained: |           | [V] | [ ] |

    >>> cells = analyze.queryHTML('//table[@class="data"]//input[@type="checkbox"]/@name', manager.contents)
    >>> manager.getControl(name=cells[1]).value = ["checked"]
    >>> manager.getControl('Update').click()
    >>> printGradebookTable(manager.contents)
    +------------+-----------+-----+-----+
    | First Name | Last Name | A   | B   |
    +------------+-----------+-----+-----+
    | Frum       | Student   | n   | n   |
    ...
    | Grum       | Student   |     |     |
    +------------+-----------+-----+-----+

    XXX: Explaining absences not yet implemented, expected result is:
    | Explained: |           | [V] | [V] |

    >>> manager.getLink('Show the whole month').click()
    >>> printGradebookTable(manager.contents)
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+
    | First Name | Last Name | 06  | 07  | 13  | 14  | 20  | 21 | 27 | 28 | Total |
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+
    | Frum       | Student   | 2   | 1   | 2   | 1   | 2   |    |    |    | 8     |
    ...
    | Grum       | Student   |     |     |     |     |     |    |    |    |       |
    +------------+-----------+-----+-----+-----+-----+-----+----+----+----+-------+

    XXX: Explaining absences not yet implemented
    | Explained: |           | [ ] | [ ] | [V] | [ ] | [ ] |    |    |    |       |

Attendance should keep working even if there are no meetings scheduled
for the current term:

    >>> manager.getLink('2005').click()

    >>> manager.getLink('Add a new term').click()
    >>> manager.getControl('Title').value = '2005 Fall 2'
    >>> manager.getControl('Start date').value = '2005-11-01'
    >>> manager.getControl('End date').value = '2005-12-31'
    >>> manager.getControl('Next').click()
    >>> manager.getControl('Saturday').click()
    >>> manager.getControl('Sunday').click()
    >>> manager.getControl('Add term').click()

We will not see any meetings in the table though...

    >>> manager.open('http://localhost/schoolyears/2005/groups/2a/attendance.html')
    >>> print analyze.queryHTML('//div[@id="content-body"]', manager.contents)[0]
    <div id="content-body">
      <form action="http://localhost/schoolyears/2005/groups/2a/attendance.html" method="post">
      ...<div>There have been no meetings in the selected term.</div>
      ...
      </form>
    </div>

But we will be able to select the previous term:

    >>> manager.getControl(name='TERM').value = ['2005-fall-1']
    >>> manager.getControl('Update').click()
    >>> printGradebookTable(manager.contents)
    +------------+-----------+----+----+----+----+----+----+----+----+-------+
    | First Name | Last Name | 04 | 05 | 11 | 12 | 18 | 19 | 25 | 26 | Total |
    +------------+-----------+----+----+----+----+----+----+----+----+-------+
    | Frum       | Student   |    |    |    |    |    |    |    |    | 8     |
    | Grum       | Student   |    |    |    |    |    |    |    |    |       |
    +------------+-----------+----+----+----+----+----+----+----+----+-------+

