Gradebook Security
------------------

It was desirable to move the security tests out of schooltool and into the
schooltool.gradebook package where they belong, so here is where they will
be.

Log in as manager:

    >>> manager = Browser('manager', 'schooltool')

Now, set up a school year (2005-2006) with two terms (Fall and
Spring):

    >>> from schooltool.app.browser.ftests import setup
    >>> setup.setUpBasicSchool()

Set up one course:

    >>> setup.addCourse('Physics I', '2005-2006')

Set up persons:

    >>> from schooltool.basicperson.browser.ftests.setup import addPerson
    >>> addPerson('Paul', 'Cardune', 'paul', 'pwd', browser=manager)
    >>> addPerson('Tom', 'Hoffman', 'tom', 'pwd', browser=manager)
    >>> addPerson('Claudia', 'Richter', 'claudia', 'pwd', browser=manager)
    >>> addPerson('Stephan', 'Richter', 'stephan', 'pwd', browser=manager)

Set up a section with instructor and students for the Fall:

    >>> setup.addSection('Physics I', '2005-2006', 'Fall',
    ...                  instructors=['Stephan'],
    ...                  members=['Tom', 'Claudia', 'Paul'])

Log in as teacher:

    >>> stephan = Browser('stephan', 'pwd')

Add a couple of activities to the default worksheet:

    >>> stephan.getLink('Gradebook').click()
    >>> stephan.getLink('New Activity').click()
    >>> stephan.getControl('Title').value = 'HW 1'
    >>> stephan.getControl('Description').value = 'Homework 1'
    >>> stephan.getControl('Category').value = ['assignment']
    >>> stephan.getControl('Maximum').value = '50'
    >>> stephan.getControl('Add').click()

    >>> stephan.getLink('New Activity').click()
    >>> stephan.getControl('Title').value = 'Quiz'
    >>> stephan.getControl('Description').value = 'Week 1 Pop Quiz'
    >>> stephan.getControl('Category').value = ['exam']
    >>> stephan.getControl('Add').click()

Add some grades:

    >>> stephan.getControl(name='Activity_paul').value = '40'
    >>> stephan.getControl(name='Activity_tom').value = '48'
    >>> stephan.getControl(name='Activity_claudia').value = '45'

    >>> stephan.getControl(name='Activity-2_paul').value = '90'
    >>> stephan.getControl(name='Activity-2_tom').value = '88'
    >>> stephan.getControl(name='Activity-2_claudia').value = '29'

    >>> stephan.getControl('Save').click()

The first test will be for the unauthenticated user.  If they hit the
'Gradebook' link at the top, they should be redirected to the login view.

    >>> unauth = Browser()
    >>> unauth.open('http://localhost/gradebook.html')
    >>> unauth.url
    'http://localhost/auth/@@login.html?nexturl=http://localhost/gradebook.html'

They should not be able to see a gradebook and certainly don't have a mygrades
view.

    >>> unauth.open('http://localhost/schoolyears/2005-2006/fall/sections/1/gradebook')
    Traceback (most recent call last):
    ...
    Unauthorized: ...

    >>> unauth.open('http://localhost/schoolyears/2005-2006/fall/sections/1/mygrades')
    Traceback (most recent call last):
    ...
    Unauthorized: ...

For managers, the default is to allow them to view, but not edit.

    >>> manager.getLink('2005-2006').click()
    >>> manager.getLink('Courses').click()
    >>> manager.getLink('Physics I').click()
    >>> manager.getLink('(Fall)').click()
    >>> manager.getLink('Gradebook', index=1).click()
    >>> manager.url
    'http://localhost/schoolyears/2005-2006/fall/sections/1/activities/Worksheet/gradebook'
    >>> manager.printQuery('//table[@class="schooltool_gradebook"][2]/tr[2]/th/div[1]')
    <div>Name</div>
    <div>Total</div>
    <div>Ave.</div>
    <div class="padded">
      <a ...>HW1</a>
    </div>
    <div class="padded">
      <a ...>Quiz</a>
    </div>
    >>> manager.printQuery('//table[@class="schooltool_gradebook"][2]/tr/td[1]/a[1]/text()')
    Cardune, Paul
    Hoffman, Tom
    Richter, Claudia
    >>> manager.printQuery('//table[@class="schooltool_gradebook"][2]/tr/td[2]/b/text()')
    130.0
    136.0
    74.0
    >>> manager.printQuery('//table[@class="schooltool_gradebook"][2]/tr/td[3]/b/text()')
    86.7%
    90.7%
    49.3%
    >>> manager.getLink('HW1').click()
    Traceback (most recent call last):
    ...
    Unauthorized: ...

Administration can't grade students by default but can give itself
the permission to do it:

    >>> manager.open('http://localhost')
    >>> manager.getLink('Manage').click()
    >>> manager.getLink('Access Control').click()
    >>> manager.getControl("The instructor of a section and school administration can edit a section's gradebook").click()
    >>> manager.getControl('Apply').click()

And try again:

    >>> manager.getLink('2005-2006').click()
    >>> manager.getLink('Courses').click()
    >>> manager.getLink('Physics I').click()
    >>> manager.getLink('(Fall)').click()
    >>> manager.getLink('Gradebook', index=1).click()
    >>> manager.getLink('HW1').click()
    >>> manager.printQuery('//h3')
    <h3>
      Grade HW 1
    </h3>
    >>> manager.getControl(name='tom').value = '30'
    >>> manager.getControl('Save').click()
    >>> manager.printQuery('//table[@class="schooltool_gradebook"][2]/tr/td[1]/a[1]/text()')
    Cardune, Paul
    Hoffman, Tom
    Richter, Claudia
    >>> manager.printQuery('//table[@class="schooltool_gradebook"][2]/tr/td[2]/b/text()')
    130.0
    118.0
    74.0
    >>> manager.printQuery('//table[@class="schooltool_gradebook"][2]/tr/td[3]/b/text()')
    86.7%
    78.7%
    49.3%

A teacher should be able to view and edit his own gradebook.

    >>> stephan.getLink('Gradebook').click()
    >>> stephan.printQuery('//table[@class="schooltool_gradebook"][2]/tr/td[1]/a[1]/text()')
    Cardune, Paul
    Hoffman, Tom
    Richter, Claudia
    >>> stephan.printQuery('//table[@class="schooltool_gradebook"][2]/tr/td[2]/b/text()')
    130.0
    118.0
    74.0
    >>> stephan.printQuery('//table[@class="schooltool_gradebook"][2]/tr/td[3]/b/text()')
    86.7%
    78.7%
    49.3%
    >>> stephan.getLink('HW1').click()
    >>> stephan.printQuery('//h3')
    <h3>
      Grade HW 1
    </h3>
    >>> stephan.getControl(name='tom').value = '50'
    >>> stephan.getControl('Save').click()
    >>> stephan.printQuery('//table[@class="schooltool_gradebook"][2]/tr/td[1]/a[1]/text()')
    Cardune, Paul
    Hoffman, Tom
    Richter, Claudia
    >>> stephan.printQuery('//table[@class="schooltool_gradebook"][2]/tr/td[2]/b/text()')
    130.0
    138.0
    74.0
    >>> stephan.printQuery('//table[@class="schooltool_gradebook"][2]/tr/td[3]/b/text()')
    86.7%
    92.0%
    49.3%

Students won't be able to see each other's grade's because the mygrades view
uses the request's principal to determine which grades to display.

    >>> claudia = Browser('claudia', 'pwd')
    >>> claudia.getLink('Gradebook').click()
    >>> claudia.url
    'http://localhost/schoolyears/2005-2006/fall/sections/1/activities/Worksheet/mygrades'
    >>> claudia.printQuery('//table[@class="schooltool_gradebook"][1]/tr/td')
    <td class="active_tab">
      <span style="font-weight: bold;">Sheet1</span>
    </td>
    >>> claudia.printQuery('//table[@class="student_gradebook"]/tr[1]/td')
    <td colspan="2" class="odd student_cell">
      <div> Ave.: 49.3%</div>
    </td>
    >>> claudia.printQuery('//table[@class="student_gradebook"]/tr[position()>1]/*[1]/div/text()')
    Activity
    HW 1 - Homework 1
    Quiz - Week 1 Pop Quiz
    >>> claudia.printQuery('//table[@class="student_gradebook"]/tr[position()>1]/*[2]/div/text()')
    Grade
    45 / 50
    29 / 100

    >>> tom = Browser('tom', 'pwd')
    >>> tom.getLink('Gradebook').click()
    >>> tom.url
    'http://localhost/schoolyears/2005-2006/fall/sections/1/activities/Worksheet/mygrades'
    >>> tom.printQuery('//table[@class="schooltool_gradebook"][1]/tr/td')
    <td class="active_tab">
      <span style="font-weight: bold;">Sheet1</span>
    </td>
    >>> tom.printQuery('//table[@class="student_gradebook"]/tr[1]/td')
    <td colspan="2" class="odd student_cell">
      <div> Ave.: 92.0%</div>
    </td>
    >>> tom.printQuery('//table[@class="student_gradebook"]/tr[position()>1]/*[1]/div/text()')
    Activity
    HW 1 - Homework 1
    Quiz - Week 1 Pop Quiz
    >>> tom.printQuery('//table[@class="student_gradebook"]/tr[position()>1]/*[2]/div/text()')
    Grade
    50 / 50
    88 / 100

Students are not be able to view a teacher's gradebook. They are redirected to
mygrades view instead.

    >>> claudia.getLink('Gradebook').click()
    >>> claudia.url
    'http://localhost/schoolyears/2005-2006/fall/sections/1/activities/Worksheet/mygrades'
    >>> claudia.printQuery('//table[@class="schooltool_gradebook"][1]/tr/td')
    <td class="active_tab">
      <span style="font-weight: bold;">Sheet1</span>
    </td>
    >>> claudia.printQuery('//table[@class="student_gradebook"]/tr[1]/td')
    <td colspan="2" class="odd student_cell">
      <div> Ave.: 49.3%</div>
    </td>
    >>> claudia.printQuery('//table[@class="student_gradebook"]/tr[position()>1]/*[1]/div/text()')
    Activity
    HW 1 - Homework 1
    Quiz - Week 1 Pop Quiz
    >>> claudia.printQuery('//table[@class="student_gradebook"]/tr[position()>1]/*[2]/div/text()')
    Grade
    45 / 50
    29 / 100
