Esempio n. 1
0
class TestDashboard(SubjectAdminSeleniumTestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.create_superuser('grandma')
        self.login('grandma')

        self.testhelper.add(nodes='uni',
                            subjects=['duck1100', 'duck1010:ln(DUCK 1010 - Programming)'],
                            periods=['2012h:begins(-1)'],
                            assignments=['week1:ln(Week One)', 'week2', 'week3', 'week4'])
        self.testhelper.add(nodes='uni',
                            subjects=['duck1010'],
                            periods=['oldperiod:begins(-100)'],
                            assignments=['oldassignment'])

    def test_dashboard(self):
        self.browseTo('')
        self.waitForCssSelector('.shortcutlist')
        self.assertTrue('Active subjects' in self.selenium.page_source)
        self.assertFalse('oldperiod' in self.selenium.page_source)
        self.assertFalse('oldassignment' in self.selenium.page_source)
        self.assertEquals(self.selenium.page_source.count('Week One'), 2)
        self.assertEquals(self.selenium.page_source.count('Add assignment'), 2)
        self.assertTrue('duck1010' in self.selenium.page_source)
        self.assertEquals(len(self.selenium.find_elements_by_link_text('Add assignment')), 2)
        self.assertEquals(len(self.selenium.find_elements_by_link_text('Week One')), 2)

        browse_all_buttons = self.selenium.find_elements_by_link_text('Browse all your subjects (including old/archived)')
        self.assertEquals(len(browse_all_buttons), 1)
        self.assertEquals(browse_all_buttons[0].get_attribute('href'),
                          self.get_absolute_url('/'))
Esempio n. 2
0
class TestSubjectListAll(SubjectAdminSeleniumTestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.create_superuser('grandma')
        self.testhelper.add(nodes='uni:admin(uniadmin)',
                            subjects=['duck1100:admin(duck1100adm)', 'duck1010:ln(DUCK 1010 - Programming)', 'duck9000'])
        self.url = '/allsubjects/'

    def _get_show_subject_url(self, subject):
        return '#/subject/{0}/'.format(subject.id)

    def test_listall(self):
        self.login('uniadmin')
        self.browseTo(self.url)
        self.waitForCssSelector('.devilry_allSubjectsList')
        self.assertTrue('All subjects' in self.selenium.page_source)
        subjectlist = self.selenium.find_element_by_css_selector('.devilry_allSubjectsList')
        self.assertEquals(len(subjectlist.find_elements_by_css_selector('li.devilry_subject')), 3)
        self.assertEquals(len(subjectlist.find_elements_by_css_selector('.devilry_subject_duck1100')), 1)
        self.assertEquals(len(subjectlist.find_elements_by_css_selector('.devilry_subject_duck1010')), 1)
        self.assertEquals(len(subjectlist.find_elements_by_css_selector('.devilry_subject_duck9000')), 1)
        self.assertTrue('DUCK 1010 - Programming' in self.selenium.page_source)
        self.assertTrue(self._get_show_subject_url(self.testhelper.duck1100) in self.selenium.page_source)
        self.assertTrue(self._get_show_subject_url(self.testhelper.duck1010) in self.selenium.page_source)
        self.assertTrue(self._get_show_subject_url(self.testhelper.duck9000) in self.selenium.page_source)

    def test_listall_limited(self):
        self.login('duck1100adm')
        self.browseTo(self.url)
        self.waitForCssSelector('.devilry_allSubjectsList')
        subjectlist = self.selenium.find_element_by_css_selector('.devilry_allSubjectsList')
        self.assertEquals(len(subjectlist.find_elements_by_css_selector('li.devilry_subject')), 1)
Esempio n. 3
0
class TestAssignment(SubjectAdminSeleniumTestCase):
    def setUp(self):
        self.testhelper = TestHelper()

    def _browseToAssignment(self, id):
        self.browseTo('/assignment/{id}/'.format(id=id))

    def test_doesnotexists(self):
        self.testhelper.create_user('normal')
        self.login('normal')
        self._browseToAssignment(100000)
        self.waitForCssSelector('.devilry_extjsextras_alertmessagelist')
        self.assertTrue('403: FORBIDDEN' in self.selenium.page_source)

    def test_doesnotexists_superadmin(self):
        self.testhelper.create_superuser('grandma')
        self.login('grandma')
        self._browseToAssignment(100000)
        self.waitForCssSelector('.devilry_extjsextras_alertmessagelist')
        self.assertTrue('404: NOT FOUND' in self.selenium.page_source)

    def test_shortcuts_render(self):
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['period1'],
                            assignments=['week2:pub(2):admin(week2admin)'])
        self.login('week2admin')
        self._browseToAssignment(self.testhelper.sub_period1_week2.id)
        self.waitForCssSelector('.devilry_subjectadmin_assignmentoverview')
        self.assertTrue('Manage students' in self.selenium.page_source)
        self.assertTrue('Manage deadlines' in self.selenium.page_source)

    def test_title(self):
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['period1'],
                            assignments=['week2:pub(2):admin(week2admin)'])
        self.login('week2admin')
        self._browseToAssignment(self.testhelper.sub_period1_week2.id)
        self.waitForCssSelector('.devilry_subjectadmin_assignmentoverview')
        self.assertEquals(self.selenium.title, 'sub.period1.week2 - Devilry')

    def test_notpublished(self):
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['period1'],
                            assignments=['week2:pub(2):admin(week2admin)'])
        self.login('week2admin')
        self._browseToAssignment(self.testhelper.sub_period1_week2.id)
        self.waitForText('>Not published')

    def test_published(self):
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['period1:begins(-2)'],
                            assignments=['week2:admin(week2admin)'])
        self.login('week2admin')
        self._browseToAssignment(self.testhelper.sub_period1_week2.id)
        self.waitForText('>Published')
class TestNodeAdminRequired(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes="tstnode.subnode:admin(normaluser)")
        self.testhelper.create_superuser("superuser")

    def test_nodeadmin_required_superuser(self):
        nodeadmin_required(self.testhelper.superuser, "", None ) # Calls is_superuser and exits without further checks

    def test_nodeadmin_required_normaluser(self):
        nodeadmin_required(self.testhelper.normaluser, "", self.testhelper.tstnode_subnode.id)

    def test_nodeadmin_required_normaluser_denied(self):
        self.assertRaises(PermissionDeniedError, nodeadmin_required, self.testhelper.normaluser, "", self.testhelper.tstnode.id)
class TestRestPreview(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni:admin(uniadmin)',
            subjects=['sub'],
            periods=['p1:admin(periodadmin):begins(-3):ends(6)'])
        self.client = RestClient()
        self.testhelper.create_superuser('superuser')

    def _get_url(self, periodid):
        return reverse('devilry_qualifiesforexam-rest-preview', kwargs={'id': periodid})

    def _getas(self, username, periodid, previewdata, pluginsessionid='tst'):
        self.client.login(username=username, password='******')
        session = self.client.session
        session['qualifiesforexam-{0}'.format(pluginsessionid)] = previewdata.serialize()
        session.save()
        return self.client.rest_get(self._get_url(periodid),
            pluginsessionid=pluginsessionid)

    def _test_getas(self, username):
        content, response = self._getas(username, self.testhelper.sub_p1.id,
            PreviewData(passing_relatedstudentids=[1, 2, 4]))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(set(content.keys()), set(['pluginoutput', 'perioddata']))
        self.assertEqual(content['pluginoutput'],
            {u'passing_relatedstudentids': [1, 2, 4]})

    def test_get_as_periodadmin(self):
        self._test_getas('periodadmin')
    def test_get_as_nodeadmin(self):
        self._test_getas('uniadmin')
    def test_get_as_superuser(self):
        self._test_getas('superuser')

    def test_getas_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._getas('nobody', self.testhelper.sub_p1.id,
            PreviewData(passing_relatedstudentids=[]))
        self.assertEqual(response.status_code, 403)

    def test_get_invalid_period(self):
        periodid = 10000
        self.assertFalse(Period.objects.filter(id=periodid).exists()) # Just to be sure we dont get false positives
        content, response = self._getas('periodadmin', periodid, PreviewData(passing_relatedstudentids=[]))
        self.assertEqual(response.status_code, 403)
Esempio n. 6
0
class TestNodeadminRequired(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='n1:admin(n1admin)')
        self.testhelper.add(nodes='n2')
        self.testhelper.create_superuser("superuser")

    def test_superuser(self):
        nodeadmin_required(self.testhelper.superuser, None) # Calls is_superuser and exits without further checks

    def test_admin_allowed(self):
        nodeadmin_required(self.testhelper.n1admin,
                                 self.testhelper.n1.id)

    def test_nonadmin_denied(self):
        self.assertRaises(PermissionDeniedError,
                          nodeadmin_required, self.testhelper.n1admin,
                          self.testhelper.n2.id) # s1admin is not admin on s2..
Esempio n. 7
0
class TestSubjectadminRequired(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni',
                            subjects=['s1:admin(s1admin)', 's2'])
        self.testhelper.create_superuser("superuser")

    def test_superuser(self):
        _subjectadmin_required(self.testhelper.superuser, None) # Calls is_superuser and exits without further checks

    def test_admin_allowed(self):
        _subjectadmin_required(self.testhelper.s1admin,
                                 self.testhelper.s1.id)

    def test_nonadmin_denied(self):
        self.assertRaises(PermissionDeniedError,
                          _subjectadmin_required, self.testhelper.s1admin,
                          self.testhelper.s2.id) # s1admin is not admin on s2..
class TestRestAggregatedGroupInfo(TestCase):
    def setUp(self):
        self.client = RestClient()
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['p1:begins(-1)'],
                            assignments=['a1:admin(a1admin)'])
        self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate(student1,student2):examiner(examiner1).d1:ends(5)')
        self.testhelper.add_to_path('uni;sub.p1.a1.g1.d2:ends(10)')
        self.group = self.testhelper.sub_p1_a1_g1
        self.url = '/devilry_subjectadmin/rest/aggregated-groupinfo/{0}'.format(self.group.id)

    def _getas(self, username):
        self.client.login(username=username, password='******')
        return self.client.rest_get(self.url)

    def test_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._getas('nobody')
        self.assertEquals(response.status_code, 403)

    def test_groupinfo(self):
        content, response = self._getas('a1admin')
        self.assertEquals(response.status_code, 200)
        self.assertEquals(set(content.keys()),
                          set(['id', 'deadlines']))
        self.assertEquals(content['id'], self.group.id)

    def test_groupinfo_superuser(self):
        self.testhelper.create_superuser('superuser')
        content, response = self._getas('superuser')
        self.assertEquals(response.status_code, 200)
        self.assertEquals(set(content.keys()),
                          set(['id', 'deadlines']))
        self.assertEquals(content['id'], self.group.id)

    def test_deadlines(self):
        content, response = self._getas('a1admin')
        deadlines = content['deadlines']
        self.assertEquals(len(deadlines), 2)
        self.assertEquals(set(deadlines[0].keys()),
                          set(['id', 'deadline', 'deliveries', 'text',
                               'offset_from_now', 'in_the_future']))
class TestRestDetailedPeriodOverview(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni:admin(uniadmin)',
            subjects=['sub'],
            periods=['p1:admin(periodadmin):begins(-3):ends(6)'])
        self.client = RestClient()
        self.testhelper.create_superuser('superuser')

    def _get_url(self, periodid):
        return reverse('devilry-subjectadmin-rest-detailedperiodoverview', kwargs={'id': periodid})

    def _getas(self, username, periodid):
        self.client.login(username=username, password='******')
        return self.client.rest_get(self._get_url(periodid))

    def _test_get_as(self, username):
        content, response = self._getas(username, self.testhelper.sub_p1.id)
        self.assertEqual(response.status_code, 200)
        # NOTE: This is tested in more detail in the API that generates the data (devilry.utils.groups_groupedby_relatedstudent_and_assignment)
        self.assertEqual(set(content.keys()),
            set([u'students_with_feedback_that_is_candidate_but_not_in_related',
                 u'students_with_no_feedback_that_is_candidate_but_not_in_related',
                 u'relatedstudents', u'assignments']))

    def test_getlist_as_periodadmin(self):
        self._test_get_as('periodadmin')
    def test_getlist_as_nodeadmin(self):
        self._test_get_as('uniadmin')
    def test_getlist_as_superuser(self):
        self._test_get_as('superuser')

    def test_get_as_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._getas('nobody', self.testhelper.sub_p1.id)
        self.assertEqual(response.status_code, 403)

    def test_get_invalid_id(self):
        content, response = self._getas('periodadmin', 10000)
        self.assertEqual(response.status_code, 403)
class TestRestToplevelNodeListing(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni:admin(uniadmin).inf:admin(infadmin)')
        self.testhelper.add(nodes='uni.fys:admin(fysadmin)')
        self.testhelper.add(nodes='uni.fys2:admin(fysadmin)')
        self.client = RestClient()

    def _geturl(self):
        return reverse('devilry_nodeadmin-rest_toplevel_nodes')

    def test_get_as_nodeadmin(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl())
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content), 1)
        self.assertEquals(content[0]['short_name'], 'inf')

    def test_multiget_as_nodeadmin(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl())
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content), 2)
        self.assertEquals([n['short_name'] for n in content], ['fys', 'fys2'])

    def test_get_as_superuser(self):
        self.testhelper.create_superuser('super')
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl())
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content), 1)
        self.assertEquals(content[0]['short_name'], 'uni')

    def test_nodata(self):
        self.testhelper.create_user('nobody')
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl())
        self.assertEquals(response.status_code, 200)
        self.assertEquals(content, [])
Esempio n. 11
0
class TestAssignmentAdminRequired(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni',
                            subjects=['duck1010'],
                            periods=['firstsem'],
                            assignments=['a1:admin(a1admin)', 'a2'])
        self.testhelper.create_superuser("superuser")
        self.assignment1 = self.testhelper.duck1010_firstsem_a1
        self.assignment2 = self.testhelper.duck1010_firstsem_a2

    def test_superuser(self):
        _assignmentadmin_required(self.testhelper.superuser, None) # Calls is_superuser and exits without further checks

    def test_admin_allowed(self):
        _assignmentadmin_required(self.testhelper.a1admin,
                                 self.assignment1.id)

    def test_nonadmin_denied(self):
        self.assertRaises(PermissionDeniedError,
                          _assignmentadmin_required, self.testhelper.a1admin,
                          self.assignment2.id) # a1admin is not admin on a2
class TestRestToplevelNodeListing(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes="uni:admin(uniadmin).inf:admin(infadmin)")
        self.testhelper.add(nodes="uni.fys:admin(fysadmin)")
        self.testhelper.add(nodes="uni.fys2:admin(fysadmin)")
        self.client = RestClient()

    def _geturl(self):
        return reverse("devilry_nodeadmin-rest_toplevel_nodes")

    def test_get_as_nodeadmin(self):
        self.client.login(username="******", password="******")
        content, response = self.client.rest_get(self._geturl())
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content), 1)
        self.assertEquals(content[0]["short_name"], "inf")

    def test_multiget_as_nodeadmin(self):
        self.client.login(username="******", password="******")
        content, response = self.client.rest_get(self._geturl())
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content), 2)
        self.assertEquals([n["short_name"] for n in content], ["fys", "fys2"])

    def test_get_as_superuser(self):
        self.testhelper.create_superuser("super")
        self.client.login(username="******", password="******")
        content, response = self.client.rest_get(self._geturl())
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content), 1)
        self.assertEquals(content[0]["short_name"], "uni")

    def test_nodata(self):
        self.testhelper.create_user("nobody")
        self.client.login(username="******", password="******")
        content, response = self.client.rest_get(self._geturl())
        self.assertEquals(response.status_code, 200)
        self.assertEquals(content, [])
Esempio n. 13
0
class TestStatusPrintView(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.create_superuser('superuser')

    def _get_url(self, status_id):
        return reverse('devilry_qualifiesforexam_statusprint', kwargs={'status_id': status_id})

    def _getas(self, username, status_id):
        self.client.login(username=username, password='******')
        return self.client.get(self._get_url(status_id))

    def test_status_not_found(self):
        response = self._getas('superuser', 1)
        self.assertEqual(response.status_code, 404)

    def test_status_forbidden(self):
        self.testhelper.add(nodes='uni',
            subjects=['sub'],
            periods=['p1:admin(periodadmin):begins(-3):ends(6)'])
        status = Status.objects.create(
                user=self.testhelper.superuser,
                period=self.testhelper.sub_p1,
                status=Status.READY)
        self.testhelper.create_user('nobody')
        response = self._getas('nobody', status.pk)
        self.assertEqual(response.status_code, 403)

    def test_status_not_ready(self):
        self.testhelper.add(nodes='uni',
            subjects=['sub'],
            periods=['p1:admin(periodadmin):begins(-3):ends(6)'])
        status = Status.objects.create(
                user=self.testhelper.superuser,
                period=self.testhelper.sub_p1,
                status=Status.NOTREADY)
        response = self._getas('superuser', status.pk)
        self.assertEqual(response.status_code, 404)
Esempio n. 14
0
class TestRestExaminerStats(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni:admin(uniadmin)',
            subjects=['sub'],
            periods=['p1:begins(-3):ends(6)'],
            assignments=['a1:admin(assignmentadmin)']
        )
        self.client = RestClient()
        self.testhelper.create_superuser('superuser')

    def _get_url(self, assignmentid):
        return reverse('devilry-subjectadmin-rest-examinerstats', kwargs={'id': assignmentid})

    def _getas(self, username, periodid):
        self.client.login(username=username, password='******')
        return self.client.rest_get(self._get_url(periodid))

    def _test_get_as(self, username):
        content, response = self._getas(username, self.testhelper.sub_p1_a1.id)
        self.assertEqual(response.status_code, 200)

    def test_perms_as_assignmentadmin(self):
        self._test_get_as('assignmentadmin')
    def test_perms_as_nodeadmin(self):
        self._test_get_as('uniadmin')
    def test_perms_as_superuser(self):
        self._test_get_as('superuser')

    def test_perms_as_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._getas('nobody', self.testhelper.sub_p1_a1.id)
        self.assertEqual(response.status_code, 403)

    def test_perms_invalid_id(self):
        content, response = self._getas('assignmentadmin', 10000)
        self.assertEqual(response.status_code, 403)
Esempio n. 15
0
class TestEmailSendingDebugView(TestCase):
    def setUp(self):
        self.client = Client()
        self.testhelper = TestHelper()
        self.nobody = self.testhelper.create_user('nobody')
        self.superuser = self.testhelper.create_superuser('superuser')
        self.url = reverse('send_email_to_students_email_sending_debug',
                           kwargs={'username': '******'})

    def test_email_sending_debug_nobody(self):
        self.client.login(username='******', password='******')
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 403)

    def test_email_sending_debug(self):
        self.testhelper.create_user('targetuser')
        self.client.login(username='******', password='******')
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 200)
        self.assertTrue('<html>' in response.content)
        self.assertTrue('*****@*****.**' in response.content)

    def test_email_sending_debug_invaliduser(self):
        self.client.login(username='******', password='******')
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 404)
        self.assertEqual(response.content, 'ERROR: User "targetuser" does not exist')

    def test_email_sending_debug_noemail(self):
        targetuser = self.testhelper.create_user('targetuser')
        targetuser.email = ''
        targetuser.save()
        self.client.login(username='******', password='******')
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.content, 'ERROR: User "targetuser" has no email address')

    def test_email_sending_debug_superuser_noemail(self):
        targetuser = self.testhelper.create_user('targetuser')
        superuser = self.testhelper.superuser
        superuser.email = ''
        superuser.save()
        self.client.login(username='******', password='******')
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.content, 'ERROR: YOU (superuser) have no email address')
Esempio n. 16
0
class TestSubjectOverview(SubjectAdminSeleniumTestCase, SubjectTestCommonMixin,
                          RenameBasenodeTestMixin, DeleteBasenodeTestMixin):
    renamebutton_id = 'subjectRenameButton'
    deletebutton_id = 'subjectDeleteButton'

    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni:admin(uniadmin,anotheruniadmin)',
                            subjects=['duck1100:admin(duck1100adm)',
                                      'duck1010:ln(DUCK 1010 - Programming):admin(duck1010adm1,duck1010adm2,duck1010adm3)'])
        self.testhelper.add(nodes='uni',
                            subjects=['duck1010'],
                            periods=['period1:ln(Period One)', 'period2:ln(Period Two)', 'period3:ln(Period Three)'])
        self.testhelper.add(nodes='uni',
                            subjects=['duck1100'],
                            periods=['spring01:ln(Spring Year One)'])

    def _get_period_url(self, period):
        return '#/period/{0}/'.format(period.id)

    def test_doesnotexists(self):
        self.login('duck1010adm1')
        self.browseToSubject(100000)
        self.waitForCssSelector('.devilry_extjsextras_alertmessagelist')
        self.assertTrue('403: FORBIDDEN' in self.selenium.page_source)

    def test_doesnotexists_superadmin(self):
        self.testhelper.create_superuser('grandma')
        self.login('grandma')
        self.browseToSubject(100000)
        self.waitForCssSelector('.devilry_extjsextras_alertmessagelist')
        self.assertTrue('404: NOT FOUND' in self.selenium.page_source)

    def test_list_of_periods(self):
        self.login('duck1010adm1')
        self.browseToSubject(self.testhelper.duck1010.id)
        self.waitForCssSelector('.devilry_subjectoverview')
        self.waitForText('DUCK 1010 - Programming')
        self.waitForCssSelector('li.devilry_period')
        periodlist = self.selenium.find_element_by_css_selector('.devilry_listofperiods')
        self.assertEquals(len(periodlist.find_elements_by_css_selector('li.devilry_period')), 3)
        self.assertTrue('Period One' in self.selenium.page_source)
        self.assertTrue('Period Two' in self.selenium.page_source)
        self.assertTrue('Period Three' in self.selenium.page_source)
        self.assertFalse('Spring Year One' in self.selenium.page_source)
        self.assertIn(self._get_period_url(self.testhelper.duck1010_period1), self.selenium.page_source)
        self.assertIn(self._get_period_url(self.testhelper.duck1010_period2), self.selenium.page_source)
        self.assertIn(self._get_period_url(self.testhelper.duck1010_period3), self.selenium.page_source)
        self.assertNotIn(self._get_period_url(self.testhelper.duck1100_spring01), self.selenium.page_source)

    def test_dangerous_panel(self):
        self.login('duck1010adm1')
        self.browseToSubject(self.testhelper.duck1010.id)
        self.waitForCssSelector('.devilry_subjectoverview')
        self.waitForText('Delete duck1010')
        self.waitForText('Rename duck1010')
        self.assertIn('Once you delete a subject, there is no going back', self.selenium.page_source)
        self.assertIn('Renaming a subject should not done without a certain amount of consideration', self.selenium.page_source)

    def test_rename(self):
        self.login('duck1010adm1')
        self.browseToSubject(self.testhelper.duck1010.id)
        self.waitForCssSelector('.devilry_subjectoverview')
        self.rename_test_helper(self.testhelper.duck1010)

    def test_rename_failure(self):
        self.login('duck1010adm1')
        self.browseToSubject(self.testhelper.duck1010.id)
        self.waitForCssSelector('.devilry_subjectoverview')
        self.rename_test_failure_helper()

    def test_delete(self):
        self.testhelper.add(nodes='uni',
                            subjects=['willbedeleted'])
        self.login('uniadmin')
        self.browseToSubject(self.testhelper.willbedeleted.id)
        self.waitForCssSelector('.devilry_subjectoverview')
        subjecturl = self.selenium.current_url
        self.perform_delete()
        self.waitFor(self.selenium, lambda s: s.current_url != subjecturl) # Will time out and fail unless the page is changed after delete
        self.assertEquals(Subject.objects.filter(id=self.testhelper.willbedeleted.id).count(), 0)

    def test_delete_notparentadmin(self):
        self.testhelper.add(nodes='uni',
                            subjects=['willbedeleted:admin(willbedeletedadm)'])
        self.login('willbedeletedadm')
        self.browseToSubject(self.testhelper.willbedeleted.id)
        self.waitForCssSelector('.devilry_subjectoverview')
        self.click_delete_button()
        self.waitForText('Only superusers can delete non-empty items') # Will time out and fail unless the dialog is shown

    def test_delete_not_empty(self):
        self.login('uniadmin')
        self.browseToSubject(self.testhelper.duck1010.id)
        self.waitForCssSelector('.devilry_subjectoverview')
        self.click_delete_button()
        self.waitForText('Only superusers can delete non-empty items') # Will time out and fail unless the dialog is shown

    def test_title(self):
        self.login('duck1010adm1')
        self.browseToSubject(self.testhelper.duck1010.id)
        self.waitForCssSelector('.devilry_subjectoverview')
        self.assertEquals(self.selenium.title, 'duck1010 - Devilry')

    def test_admins(self):
        self.testhelper.duck1010adm3.devilryuserprofile.full_name = 'Duck1010 admin three'
        self.testhelper.duck1010adm3.devilryuserprofile.save()
        self.login('duck1010adm1')
        self.browseToSubject(self.testhelper.duck1010.id)
        self.waitForCssSelector('.devilry_subjectadmin_administratorlist')
        adminlist = self.selenium.find_element_by_css_selector('.devilry_subjectadmin_administratorlist')
        self.assertEquals(len(adminlist.find_elements_by_css_selector('li')), 3)
        self.assertTrue('>duck1010adm1<' in self.selenium.page_source)
        self.assertTrue('>duck1010adm2<' in self.selenium.page_source)
        self.assertFalse('>duck1010adm3<' in self.selenium.page_source)
        self.assertTrue('Duck1010 admin three' in self.selenium.page_source)

    def test_inherited_admins(self):
        self.testhelper.uniadmin.devilryuserprofile.full_name = 'Uni admin'
        self.testhelper.uniadmin.devilryuserprofile.save()
        self.login('duck1010adm1')
        self.browseToSubject(self.testhelper.duck1010.id)
        self.waitForCssSelector('.devilry_subjectadmin_inherited_administratorlist')
        adminlist = self.selenium.find_element_by_css_selector('.devilry_subjectadmin_inherited_administratorlist')
        self.assertEquals(len(adminlist.find_elements_by_css_selector('li')), 2)
        self.assertTrue('>anotheruniadmin<' in self.selenium.page_source)
        self.assertFalse('>uniadmin<' in self.selenium.page_source)
        self.waitForCssSelector('.devilry_subjectadmin_inherited_administratorlist .inherited_administratorlistitem_uniadmin')
        self.assertTrue('Uni admin' in self.selenium.page_source)

    def test_breadcrumb(self):
        self.login('duck1010adm1')
        self.browseToSubject(self.testhelper.duck1010.id)
        breadcrumbtext = self.get_breadcrumbstring('duck1010')
        self.assertEquals(breadcrumbtext, ['All subjects', 'duck1010'])
Esempio n. 17
0
class TestSearchForUsers(TestCase):
    def setUp(self):
        self.client = RestClient()
        for username, fullname in [('baldr', 'God of Beauty'),
                                   ('freyja', 'Goddess of Love'),
                                   ('freyr', 'God of Fertility'),
                                   ('kvasir', 'God of Inspiration'),
                                   ('loki', 'Trickster and god of Mischief'),
                                   ('thor', 'God of thunder and Battle'),
                                   ('odin', 'The "All Father"')]:
            user = User.objects.create(username=username,
                                       email='{0}@{1}.com'.format(fullname.lower().replace(' ', '.'),
                                                                  username))
            user.devilryuserprofile.full_name = fullname
            user.devilryuserprofile.save()

        self.testhelper = TestHelper()
        self.testhelper.add(nodes="uni:admin(uniadmin)",
                            subjects=["sub:admin(subadmin)"],
                            periods=["p1:admin(p1admin)"],
                            assignments=["a1:admin(a1admin)"])
        self.url = '/devilry_usersearch/search'


    def _listas(self, username, **data):
        self.client.login(username=username, password='******')
        return self.client.rest_get(self.url, **data)

    def _searchas(self, username, query):
        return self._listas(username, query=query)[0]

    def _test_search_as(self, username):
        content, response = self._listas(username, query='')
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(self._searchas(username, 'fre')), 2)
        self.assertEquals(len(self._searchas(username, 'fr')), 0)
        self.assertEquals(len(self._searchas(username, 'f')), 0)
        self.assertEquals(len(self._searchas(username, 'GOD')), 6)
        self.assertEquals(len(self._searchas(username, 'god')), 6)
        self.assertEquals(len(self._searchas(username, 'thor')), 1)
        self.assertEquals(len(self._searchas(username, 'tHoR')), 1)
        thor = self._searchas(username, 'tHoR')[0]
        self.assertEquals(thor,
                          {u'username': u'thor',
                           u'id': User.objects.get(username='******').id,
                           u'full_name': u'God of thunder and Battle',
                           u'languagecode': None,
                           u'email': u'*****@*****.**'})

    def test_search_nodeadmin(self):
        self._test_search_as('uniadmin')

    def test_search_subjectadmin(self):
        self._test_search_as('subadmin')

    def test_search_periodadmin(self):
        self._test_search_as('p1admin')

    def test_search_assignmentadmin(self):
        self._test_search_as('a1admin')

    def test_search_superadmin(self):
        self.testhelper.create_superuser('grandma')
        self._test_search_as('grandma')

    def test_search_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._listas('nobody', query='')
        self.assertEquals(response.status_code, 403)

    def test_search_limit(self):
        for index in xrange(15):
            username = '******'.format(index)
            user = User.objects.create(username=username,
                                       email='{0}@example.com'.format(username))
        self.assertEquals(len(self._searchas('uniadmin', 'student')), 10)
Esempio n. 18
0
class TestUserInfo(TestCase):
    def setUp(self):
        self.client = RestClient()

        self.url = '/devilry_authenticateduserinfo/userinfo'
        self.testhelper = TestHelper()
        self.testhelper.add(nodes="uni:admin(nodeadm)",
                            subjects=["sub:admin(subjectadm)"],
                            periods=["p1:admin(periodadm):begins(-2):ends(6)"],
                            assignments=["a1:admin(assignmentadm)"])
        self.testhelper.create_superuser('grandma')
        self.testhelper.create_user('nobody')
        self.testhelper.add_to_path('uni;sub.p1.a1.g1:examiner(examiner1):candidate(student1)')

    def _getas(self, username):
        self.client.login(username=username, password='******')
        return self.client.rest_get(self.url)

    def _get_and_sanitytest_as(self, username, is_superuser=False,
                               is_nodeadmin=False, is_subjectadmin=False,
                               is_periodadmin=False, is_assignmentadmin=False,
                               is_student=False, is_examiner=False):
        content, response = self._getas(username)
        self.assertEquals(response.status_code, 200)
        self.assertEquals(set(content.keys()),
                          set(['id', 'username', 'languagecode', 'email',
                               'full_name', 'is_superuser', 'is_nodeadmin',
                               'is_subjectadmin', 'is_periodadmin',
                               'is_assignmentadmin', 'is_examiner', 'is_student']))
        self.assertEquals(content['is_superuser'], is_superuser)
        self.assertEquals(content['is_nodeadmin'], is_nodeadmin)
        self.assertEquals(content['is_subjectadmin'], is_subjectadmin)
        self.assertEquals(content['is_periodadmin'], is_periodadmin)
        self.assertEquals(content['is_assignmentadmin'], is_assignmentadmin)
        self.assertEquals(content['is_student'], is_student)
        self.assertEquals(content['is_examiner'], is_examiner)
        return content

    def test_as_superuser(self):
        content = self._get_and_sanitytest_as('grandma', is_superuser=True)

    def test_as_nodeadmin(self):
        content = self._get_and_sanitytest_as('nodeadm', is_nodeadmin=True)

    def test_as_subjectadmin(self):
        content = self._get_and_sanitytest_as('subjectadm', is_subjectadmin=True)

    def test_as_periodadmin(self):
        content = self._get_and_sanitytest_as('periodadm', is_periodadmin=True)

    def test_as_assignmentadmin(self):
        content = self._get_and_sanitytest_as('assignmentadm', is_assignmentadmin=True)

    def test_as_student(self):
        content = self._get_and_sanitytest_as('student1', is_student=True)

    def test_as_examiner(self):
        content = self._get_and_sanitytest_as('examiner1', is_examiner=True)

    def test_as_nobody(self):
        nobody = self.testhelper.nobody
        nobody.devilryuserprofile.full_name = 'A true nobody'
        nobody.devilryuserprofile.languagecode = 'en_US'
        nobody.devilryuserprofile.save()

        content = self._get_and_sanitytest_as('nobody')
        self.assertEquals(content['email'], '*****@*****.**')
        self.assertEquals(content['full_name'], 'A true nobody')
        self.assertEquals(content['languagecode'], 'en_US')
        self.assertEquals(content['username'], 'nobody')
        self.assertEquals(content['id'], self.testhelper.nobody.id)
Esempio n. 19
0
class TestRestSearchAdminContent(TestCase, AssertSearchResultMixin):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni:admin(uniadmin):ln(Test Uni)',
            subjects=['sub:admin(subadmin):ln(Test Sub)'],
            periods=['p1:begins(-2):admin(p1admin):ln(Test P1)'],
            assignments=['a1:admin(a1admin):ln(Test A1)'],
            assignmentgroups=['TestGroup1:candidate(student1)']
        )

        self.client = RestClient()
        self.url = reverse('devilry_search_admincontent')

    def _getas(self, username, **data):
        self.client.login(username=username, password='******')
        return self.client.rest_get(self.url, **data)

    def _test_perms_topnodeorsuper(self, username):
        with HaystackTestSettings():
            content, response = self._getas(username, search='Test')
            matches = content['matches']
            self.assertEqual(len(matches), 5)
            self.assert_has_search_result(matches, type='core_node', title='Test Uni')
            self.assert_has_search_result(matches, type='core_subject', title='Test Sub')
            self.assert_has_search_result(matches, type='core_period', title='Test P1')
            self.assert_has_search_result(matches, type='core_assignment', title='Test A1')
            self.assert_has_search_result(matches, type='core_assignmentgroup',
                title='Test A1', students=['student1'])

    def test_perms_uniadmin(self):
        self._test_perms_topnodeorsuper('uniadmin')

    def test_perms_superuser(self):
        self.testhelper.create_superuser('superuser')
        self._test_perms_topnodeorsuper('superuser')

    def test_perms_subjectadmin(self):
        with HaystackTestSettings():
            content, response = self._getas('subadmin', search='Test')
            matches = content['matches']
            self.assertEqual(len(matches), 4)
            self.assert_has_search_result(matches, type='core_subject', title='Test Sub')
            self.assert_has_search_result(matches, type='core_period', title='Test P1')
            self.assert_has_search_result(matches, type='core_assignment', title='Test A1')
            self.assert_has_search_result(matches, type='core_assignmentgroup',
                title='Test A1', students=['student1'])

    def test_perms_periodadmin(self):
        with HaystackTestSettings():
            content, response = self._getas('p1admin', search='Test')
            matches = content['matches']
            self.assertEqual(len(matches), 3)
            self.assert_has_search_result(matches, type='core_period', title='Test P1')
            self.assert_has_search_result(matches, type='core_assignment', title='Test A1')
            self.assert_has_search_result(matches, type='core_assignmentgroup',
                title='Test A1', students=['student1'])

    def test_perms_assignmentadmin(self):
        with HaystackTestSettings():
            content, response = self._getas('a1admin', search='Test')
            matches = content['matches']
            self.assertEqual(len(matches), 2)
            self.assert_has_search_result(matches, type='core_assignment', title='Test A1')
            self.assert_has_search_result(matches, type='core_assignmentgroup',
                title='Test A1', students=['student1'])
Esempio n. 20
0
class TestRestDeadlinesBulkUpdateReadOrDelete(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['p1:begins(-2)']) # 2 months ago 
        self.testhelper.sub_p1.start_time = datetime(2000, 1, 1, 22, 30, 49)
        self.testhelper.sub_p1.save()
        self.testhelper.add_to_path('uni;sub.p1.a1:admin(adm):pub(0)') # 0 days after period begins + 2 sec
        self.client = RestClient()

        for groupnum in xrange(3):
            # deadline 5 days after assignment starts
            self.testhelper.add_to_path('uni;sub.p1.a1.g{0}:candidate(cand1):examiner(exam1).d1:ends(5)'.format(groupnum))


    def _geturl(self, deadline=None):
        deadline = deadline or self.testhelper.sub_p1_a1_g1_d1
        bulkdeadline_id = encode_bulkdeadline_id(deadline)
        return '/devilry_subjectadmin/rest/deadlinesbulk/{0}/{1}'.format(self.testhelper.sub_p1_a1.id,
                                                                         bulkdeadline_id)

    def test_encode_unique_bulkdeadline_id(self):
        d = Deadline(deadline=datetime(2000, 12, 24, 22, 30, 49))
        self.assertEquals(encode_bulkdeadline_id(d),
                          '2000-12-24T22_30_49--')
        d.text = 'Hello world'
        self.assertEquals(encode_bulkdeadline_id(d),
                          '2000-12-24T22_30_49--{0}'.format(sha1hash('Hello world')))
        # Ensure unicode works
        d.text = u'\u00e5ello world'
        self.assertEquals(encode_bulkdeadline_id(d),
                          '2000-12-24T22_30_49--{0}'.format(sha1hash(u'\u00e5ello world')))


    def test_decode_unique_bulkdeadline_id(self):
        self.assertEquals(decode_bulkdeadline_id('2000-12-24T22_30_49--'),
                          (datetime(2000, 12, 24, 22, 30, 49), ''))
        self.assertEquals(decode_bulkdeadline_id('2000-12-24T22_30_49--{0}'.format(sha1hash('Hello world'))),
                          (datetime(2000, 12, 24, 22, 30, 49), sha1hash('Hello world')))


    def _putas(self, username, data):
        self.client.login(username=username, password='******')
        return self.client.rest_put(self._geturl(), data)

    def test_put(self):
        self.assertEquals(self.testhelper.sub_p1_a1.publishing_time, datetime(2000, 1, 1, 22, 30, 51))
        self.assertEquals(self.testhelper.sub_p1_a1_g1_d1.deadline,
                          datetime(2000, 1, 1, 22, 30) + timedelta(days=5))

        new_deadline = datetime(2004, 12, 24, 20, 30)
        content, response = self._putas('adm', {'deadline': format_datetime(new_deadline),
                                                'text': 'Hello'})
        self.assertEquals(response.status_code, 200)
        self.assertEquals(decode_bulkdeadline_id(content['bulkdeadline_id'])[0],
                          new_deadline)
        self.assertEquals(len(content['groups']), 3)
        self.assertEquals(content['text'], 'Hello')
        self.assertEquals(content['deadline'], format_datetime(new_deadline))
        for groupnum in xrange(3):
            deadline_id = getattr(self.testhelper, 'sub_p1_a1_g{0}_d1'.format(groupnum)).id
            deadline = Deadline.objects.get(id=deadline_id)
            self.assertEquals(deadline.deadline, new_deadline)
            self.assertEquals(deadline.text, 'Hello')

    def test_put_nonetext(self):
        self.assertEquals(self.testhelper.sub_p1_a1.publishing_time, datetime(2000, 1, 1, 22, 30, 51))
        self.assertEquals(self.testhelper.sub_p1_a1_g1_d1.deadline,
                          datetime(2000, 1, 1, 22, 30) + timedelta(days=5))

        new_deadline = datetime(2004, 12, 24, 20, 30)
        content, response = self._putas('adm', {'deadline': format_datetime(new_deadline),
                                                'text': None})
        self.assertEquals(response.status_code, 200)
        for groupnum in xrange(3):
            deadline_id = getattr(self.testhelper, 'sub_p1_a1_g{0}_d1'.format(groupnum)).id
            deadline = Deadline.objects.get(id=deadline_id)
            self.assertEquals(deadline.deadline, new_deadline)
            self.assertEquals(deadline.text, '')

    def test_put_before_publishingtime(self):
        new_deadline = datetime(1990, 1, 1, 20, 30, 40)
        content, response = self._putas('adm', {'deadline': format_datetime(new_deadline),
                                                'text': None})
        self.assertEquals(response.status_code, 400)
        self.assertEquals(content['errors'], ['Deadline cannot be before publishing time.'])

    def test_put_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._putas('nobody', {})
        self.assertEquals(response.status_code, 403)

    def test_put_with_bulkdeadline_id(self):
        new_deadline = datetime(2004, 12, 24, 20, 30)
        content, response = self._putas('adm', {'deadline': format_datetime(new_deadline),
                                                'bulkdeadline_id': 'ignored'})
        self.assertEquals(response.status_code, 200)

    def test_put_group_ids(self):
        new_deadline = datetime(2004, 12, 24, 20, 30)
        g1 = self.testhelper.sub_p1_a1_g1
        g2 = self.testhelper.sub_p1_a1_g2
        self.assertEquals(g1.deadlines.count(), 1)

        content, response = self._putas('adm', {'deadline': format_datetime(new_deadline),
                                                'text': 'Updated',
                                                'group_ids': [g1.id, g2.id]})
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content['groups']), 2)
        group_ids = set([g['id'] for g in content['groups']])
        self.assertEquals(group_ids, set([g1.id, g2.id]))

        for group in g1, g2:
            group = self.testhelper.reload_from_db(group)
            self.assertEquals(group.deadlines.count(), 1)
            deadline = group.deadlines.all()[0]
            self.assertEquals(deadline.deadline, new_deadline)
            self.assertEquals(deadline.text, 'Updated')



    def _getas(self, username, **data):
        self.client.login(username=username, password='******')
        return self.client.rest_get(self._geturl(), **data)

    def test_get(self):
        content, response = self._getas('adm')
        self.assertEquals(response.status_code, 200)
        self.assertEquals(decode_bulkdeadline_id(content['bulkdeadline_id'])[0],
                          self.testhelper.sub_p1_a1_g1_d1.deadline)
        self.assertEquals(content['deadline'],
                          format_datetime(self.testhelper.sub_p1_a1_g1_d1.deadline))
        self.assertEquals(content['text'], None)
        self.assertEquals(len(content['groups']), 3)

    def test_get_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._getas('nobody')
        self.assertEquals(response.status_code, 403)

    def _deleteas(self, username, deadline=None):
        self.client.login(username=username, password='******')
        return self.client.rest_delete(self._geturl(deadline))

    def test_delete_sanity(self):
        # Test that the deadline method actually does what it is supposed to do (only deletes what it should delete)
        new_deadline = datetime(2004, 12, 24, 20, 30)
        created_deadline = None
        for groupnum in xrange(2):
            group = getattr(self.testhelper, 'sub_p1_a1_g{0}'.format(groupnum))
            self.assertEquals(1, group.deadlines.count())
            created_deadline = group.deadlines.create(deadline=new_deadline) # NOTE: Does not matter which deadline object we user, since we only need the datetime and text to generate bulkdeadline_id
            self.assertEquals(2, group.deadlines.count())
        self.testhelper.sub_p1_a1_g2.deadlines.create(deadline=datetime(2006, 12, 24, 20, 30))

        self.testhelper.create_superuser('superuser')
        content, response = self._deleteas('superuser', deadline=created_deadline)
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content['deleted_deadline_ids']), 2)
        self.assertEquals(1, self.testhelper.sub_p1_a1_g0.deadlines.count())
        self.assertEquals(1, self.testhelper.sub_p1_a1_g1.deadlines.count())
        self.assertEquals(2, self.testhelper.sub_p1_a1_g2.deadlines.count())

    def test_delete_with_content_as_superuser(self):
        self.testhelper.create_superuser('superuser')
        self.testhelper.add_delivery('sub.p1.a1.g1', {'bad.py': ['print ', 'bah']})
        self.testhelper.add_feedback('sub.p1.a1.g1', verdict={'grade': 'F', 'points': 30, 'is_passing_grade': False})
        content, response = self._deleteas('superuser')
        self.assertEquals(response.status_code, 200)

    def test_delete_with_content_as_assignmentadm(self):
        self.testhelper.add_delivery('sub.p1.a1.g1', {'bad.py': ['print ', 'bah']})
        self.testhelper.add_feedback('sub.p1.a1.g1', verdict={'grade': 'F', 'points': 30, 'is_passing_grade': False})
        content, response = self._deleteas('adm')
        self.assertEquals(response.status_code, 403)

    def test_delete_without_content_as_assignmentadm(self):
        content, response = self._deleteas('adm')
        self.assertEquals(response.status_code, 200)

    def test_delete_as_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._deleteas('nobody')
        self.assertEquals(response.status_code, 403)
Esempio n. 21
0
class TestAssignment(SubjectAdminSeleniumTestCase):
    def setUp(self):
        self.testhelper = TestHelper()

    def _loginToAssignment(self, username, id):
        self.loginTo(username, '/assignment/{id}/'.format(id=id))

    def test_doesnotexists(self):
        self.testhelper.create_user('normal')
        self._loginToAssignment('normal', 100000)
        self.waitForCssSelector('.devilry_extjsextras_alertmessagelist')
        self.assertTrue('403: FORBIDDEN' in self.selenium.page_source)

    def test_doesnotexists_superadmin(self):
        self.testhelper.create_superuser('grandma')
        self._loginToAssignment('grandma', 100000)
        self.waitForCssSelector('.devilry_extjsextras_alertmessagelist')
        self.assertTrue('404: NOT FOUND' in self.selenium.page_source)

    def test_no_students(self):
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['period1'],
                            assignments=['week2:pub(2):admin(week2admin)'])
        self._loginToAssignment('week2admin', self.testhelper.sub_period1_week2.id)
        overview = self.waitForAndFindElementByCssSelector('.devilry_subjectadmin_assignmentoverview')
        self.waitForText('This assignment has no students. You need to add students', within=overview)

    def test_shortcuts_render(self):
        self.testhelper.add(nodes='uni',
            subjects=['sub'],
            periods=['period1'],
            assignments=['week2:pub(2):admin(week2admin)'],
            assignmentgroups=['g1:candidate(student1)']
        )
        self._loginToAssignment('week2admin', self.testhelper.sub_period1_week2.id)
        self.waitForCssSelector('.devilry_subjectadmin_assignmentoverview')
        self.assertTrue('@@manage-students' in self.selenium.page_source)
        self.assertTrue('@@bulk-manage-deadlines' in self.selenium.page_source)
        self.assertTrue('@@passed-previous-period' in self.selenium.page_source)

    def test_title(self):
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['period1'],
                            assignments=['week2:pub(2):admin(week2admin)'])
        self._loginToAssignment('week2admin', self.testhelper.sub_period1_week2.id)
        self.waitForCssSelector('.devilry_subjectadmin_assignmentoverview')
        self.waitFor(self.selenium, lambda s: s.title == 'sub.period1.week2 - Devilry')

    def test_notpublished(self):
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['period1'],
                            assignments=['week2:pub(2):admin(week2admin)'])
        self._loginToAssignment('week2admin', self.testhelper.sub_period1_week2.id)
        self.waitForCssSelector('.devilry_subjectadmin_editpublishingtime_widget .text-warning')

    def test_published(self):
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['period1:begins(-2)'],
                            assignments=['week2:admin(week2admin)'])
        self._loginToAssignment('week2admin', self.testhelper.sub_period1_week2.id)
        self.waitForCssSelector('.devilry_subjectadmin_editpublishingtime_widget .text-success')
class TestRestStatus(TransactionTestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni:admin(uniadmin)',
            subjects=['sub'],
            periods=[
                'oldperiod:admin(periodadmin):begins(-12):ends(2)',
                'p1:admin(periodadmin):begins(-3):ends(6)',
                'p2:admin(periodadmin):begins(-1):ends(6)'])
        self.client = RestClient()
        self.url = reverse('devilry_qualifiesforexam-rest-status')
        self.testhelper.create_superuser('superuser')

        qualifiesforexam_plugins.add(
            id = 'devilry_qualifiesforexam.test.noop-plugin',
            url = '/some/noop-url',
            title = 'Noop',
            post_statussave=noop,
            description = 'noop',
            pluginsettings_summary_generator = lambda status: 'noop summary'
        )

    def tearDown(self):
        for pluginid in ('devilry_qualifiesforexam.test.plugin', 'devilry_qualifiesforexam.test.noop-plugin'):
            if pluginid in qualifiesforexam_plugins:
                del qualifiesforexam_plugins.items[pluginid]

    def _get_url(self, periodid=None):
        if periodid:
            return '{0}{1}'.format(self.url, periodid)
        else:
            return self.url

    def _create_relatedstudent(self, username, fullname=None):
        user = getattr(self.testhelper, username, None)
        if not user:
            user = self.testhelper.create_user(username, fullname=fullname)
        relstudent = self.testhelper.sub_p1.relatedstudent_set.create(user=user)
        return relstudent

    def _postas(self, username, data):
        self.client.login(username=username, password='******')
        return self.client.rest_post(self._get_url(), data)

    def _test_post_as(self, username):
        self.assertEquals(Status.objects.count(), 0)
        relatedStudent1 = self._create_relatedstudent('student1', 'Student One')
        relatedStudent2 = self._create_relatedstudent('student2', 'Student Two')
        content, response = self._postas(username, {
            'period': self.testhelper.sub_p1.id,
            'status': 'ready',
            'message': 'This is a test',
            'plugin': 'devilry_qualifiesforexam.test.noop-plugin',
            'pluginsessionid': 'tst',
            'passing_relatedstudentids': [relatedStudent1.id]
        })
        self.assertEquals(response.status_code, 201)
        self.assertEquals(Status.objects.count(), 1)
        status = Status.objects.all()[0]
        self.assertEquals(status.period, self.testhelper.sub_p1)
        self.assertEquals(status.status, 'ready')
        self.assertEquals(status.message, 'This is a test')
        self.assertEquals(status.plugin, 'devilry_qualifiesforexam.test.noop-plugin')

        self.assertEqual(status.students.count(), 2)
        qualifies1 = status.students.get(relatedstudent=relatedStudent1)
        qualifies2 = status.students.get(relatedstudent=relatedStudent2)
        self.assertTrue(qualifies1.qualifies)
        self.assertFalse(qualifies2.qualifies)

    def test_post_as_periodadmin(self):
        self._test_post_as(self.testhelper.periodadmin)

    def test_post_as_nodeadmin(self):
        self._test_post_as(self.testhelper.uniadmin)

    def test_post_as_superuser(self):
        self._test_post_as(self.testhelper.superuser)

    def test_post_as_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._postas('nobody', {
            'period': self.testhelper.sub_p1.id,
            'status': 'ready',
            'message': 'This is a test',
            'plugin': 'devilry_qualifiesforexam.test.noop-plugin',
            'pluginsessionid': 'tst',
            'passing_relatedstudentids': [10]
        })
        self.assertEqual(response.status_code, 403)

    def test_post_almostready(self):
        relatedStudent1 = self._create_relatedstudent('student1', 'Student One')
        relatedStudent2 = self._create_relatedstudent('student2', 'Student Two')
        content, response = self._postas('periodadmin', {
            'period': self.testhelper.sub_p1.id,
            'status': 'almostready',
            'message': 'This is a test',
            'plugin': 'devilry_qualifiesforexam.test.noop-plugin',
            'pluginsessionid': 'tst',
            'passing_relatedstudentids': [relatedStudent1.id],
            'notready_relatedstudentids': [relatedStudent2.id]
        })
        self.assertEquals(response.status_code, 201)
        status = Status.objects.all()[0]
        self.assertEquals(status.status, 'almostready')
        self.assertEqual(status.students.count(), 2)
        qualifies1 = status.students.get(relatedstudent=relatedStudent1)
        qualifies2 = status.students.get(relatedstudent=relatedStudent2)
        self.assertTrue(qualifies1.qualifies)
        self.assertIsNone(qualifies2.qualifies)

    def test_post_notreadystudents_with_invalidstatus(self):
        relatedStudent1 = self._create_relatedstudent('student1', 'Student One')
        content, response = self._postas('periodadmin', {
            'period': self.testhelper.sub_p1.id,
            'status': 'ready', # Could choose any status except almostready for this test to be valid
            'plugin': 'devilry_qualifiesforexam.test.noop-plugin',
            'pluginsessionid': 'tst',
            'notready_relatedstudentids': [relatedStudent1.id]
        })
        self.assertEquals(response.status_code, 400)
        self.assertEqual(content['details'],
            u'Only the ``almostready`` status allows marking students as not ready for export.')

    def test_post_notready_check_studentsignored(self):
        relatedStudent1 = self._create_relatedstudent('student1', 'Student One')
        content, response = self._postas('periodadmin', {
            'period': self.testhelper.sub_p1.id,
            'status': 'notready',
            'pluginsessionid': 'tst',
            'message': 'Test'
        })
        self.assertEquals(response.status_code, 201)
        status = Status.objects.all()[0]
        self.assertEquals(status.status, 'notready')
        self.assertEquals(status.message, 'Test')
        self.assertEqual(status.students.count(), 0)

    def test_post_notready_messagerequired(self):
        relatedStudent1 = self._create_relatedstudent('student1', 'Student One')
        content, response = self._postas('periodadmin', {
            'period': self.testhelper.sub_p1.id,
            'status': 'notready',
            'pluginsessionid': 'tst',
            'message': '  ',
            'plugin': 'devilry_qualifiesforexam.test.noop-plugin'
        })
        self.assertEquals(response.status_code, 400)
        self.assertEqual(content['errors'][0], u'Message can not be empty when status is ``notready``.')

    def test_post_invalidstatus(self):
        relatedStudent1 = self._create_relatedstudent('student1', 'Student One')
        content, response = self._postas('periodadmin', {
            'period': self.testhelper.sub_p1.id,
            'status': 'invalidstatus',
            'pluginsessionid': 'tst',
            'plugin': 'devilry_qualifiesforexam.test.noop-plugin',
            'passing_relatedstudentids': [relatedStudent1.id]
        })
        self.assertEqual(response.status_code, 400)
        self.assertEqual(content['field_errors']['status'][0],
            u'Select a valid choice. invalidstatus is not one of the available choices.')


    def _getinstanceas(self, username, periodid):
        self.client.login(username=username, password='******')
        return self.client.rest_get(self._get_url(periodid))

    def _test_getinstance_as(self, username):
        relatedStudent1 = self._create_relatedstudent('student1', 'Student One')
        relatedStudent2 = self._create_relatedstudent('student2', 'Student Two')
        status = Status(
            period = self.testhelper.sub_p1,
            status = 'ready',
            message = 'Test',
            user = getattr(self.testhelper, username),
            plugin = 'devilry_qualifiesforexam.test.noop-plugin'
        )
        status.save()
        status.students.create(relatedstudent=relatedStudent1, qualifies=True)
        status.students.create(relatedstudent=relatedStudent2, qualifies=False)

        content, response = self._getinstanceas(username, self.testhelper.sub_p1.id)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(set(content.keys()),
            set(['id', 'perioddata', 'statuses', u'is_active', u'short_name', u'long_name', u'subject']))
        self.assertEqual(content['id'], self.testhelper.sub_p1.id)
        statuses = content['statuses']
        self.assertEqual(len(statuses), 1)
        self.assertEqual(set(statuses[0].keys()),
            set([u'id', u'status', u'plugin', u'statustext',
                 u'period', u'passing_relatedstudentids_map',
                 u'user', u'message', u'createtime', u'pluginsettings_summary',
                 u'plugin_description', u'plugin_title']))
        self.assertEqual(statuses[0]['period'], self.testhelper.sub_p1.id)
        self.assertEqual(statuses[0]['status'], 'ready')
        self.assertEqual(statuses[0]['message'], 'Test')
        self.assertEqual(statuses[0]['plugin'], 'devilry_qualifiesforexam.test.noop-plugin')
        self.assertEqual(statuses[0]['pluginsettings_summary'], 'noop summary')
        self.assertIn(str(relatedStudent1.id), statuses[0]['passing_relatedstudentids_map'])


    def test_getinstance_as_periodadmin(self):
        self._test_getinstance_as('periodadmin')
    def test_getinstance_as_nodeadmin(self):
        self._test_getinstance_as('uniadmin')
    def test_getinstance_as_superuser(self):
        self._test_getinstance_as('superuser')

    def test_getinstanceas_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._getinstanceas('nobody', self.testhelper.sub_p1.id)
        self.assertEqual(response.status_code, 403)

    def test_getinstance_no_statuses(self):
        content, response = self._getinstanceas('periodadmin', self.testhelper.sub_p1.id)
        self.assertEqual(response.status_code, 404)
        self.assertEquals(content['detail'], u'The period has no statuses')

    def test_getinstance_invalid_period(self):
        periodid = 10000
        self.assertFalse(Period.objects.filter(id=periodid).exists()) # Just to be sure we dont get false positives
        content, response = self._getinstanceas('periodadmin', periodid)
        self.assertEqual(response.status_code, 404)
        self.assertEquals(content['detail'], u'The period with ID 10000 does not exist')



    def _getlistas(self, username, **kwargs):
        self.client.login(username=username, password='******')
        return self.client.rest_get(self._get_url(), **kwargs)

    def _createlistteststatus(self, period, status='ready',
                              plugin='devilry_qualifiesforexam.test.noop-plugin'):
        status = Status(
            period = period,
            status = status,
            message = 'Test',
            user = self.testhelper.periodadmin,
            plugin = plugin
        )
        status.full_clean()
        status.save()
        return status

    def _test_getlist_as(self, username):
        self._createlistteststatus(self.testhelper.sub_oldperiod)
        self._createlistteststatus(self.testhelper.sub_p1, status='notready', plugin='')
        import time
        time.sleep(0.1) # Sleep to make sure the status below is the active status
        status = self._createlistteststatus(self.testhelper.sub_p1)

        content, response = self._getlistas(username)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(content), 2)
        p1info = content[0]
        self.assertEqual(p1info['id'], self.testhelper.sub_p1.id)
        self.assertEqual(p1info['active_status']['id'], status.id)
        p2info = content[1]
        self.assertEqual(p2info['id'], self.testhelper.sub_p2.id)
        self.assertEqual(p2info['active_status'], None)

    def test_getlist_as_periodadmin(self):
        self._test_getlist_as('periodadmin')
    def test_getlist_as_nodeadmin(self):
        self._test_getlist_as('uniadmin')
    def test_getlist_as_superuser(self):
        self._test_getlist_as('superuser')

    def test_getlist_as_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._getlistas('nobody')
        self._createlistteststatus(self.testhelper.sub_p1,
            status='notready', plugin='')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(content), 0)


    def test_get_within_node(self):
        self.testhelper.add(nodes='uni.extra:admin(extraadmin)',
            subjects=['othersub'],
            periods=['p1:admin(periodadmin):begins(-3):ends(6)'])
        content, response = self._getlistas('extraadmin', node_id=self.testhelper.uni_extra.id)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(content), 1)
        p1info = content[0]
        self.assertEqual(p1info['id'], self.testhelper.othersub_p1.id)

    def test_get_within_node_notactive(self):
        self.testhelper.add(nodes='uni.extra:admin(extraadmin)',
            subjects=['othersub'],
            periods=['old:admin(periodadmin):begins(-12):ends(6)'])
        content, response = self._getlistas('extraadmin', node_id=self.testhelper.uni_extra.id)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(content), 0)

    def test_get_within_node_notadmin_on_requested(self):
        self.testhelper.add(nodes='uni.extra:admin(extraadmin)')
        content, response = self._getlistas('extraadmin', node_id=self.testhelper.uni.id)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(content), 0)


    def test_save_settings(self):
        savedsettings = {}
        def save_settings(status, settings):
            savedsettings['status'] = status
            savedsettings['settings'] = settings

        qualifiesforexam_plugins.add(
            id = 'devilry_qualifiesforexam.test.plugin',
            url = '/some/url',
            title = 'Test',
            description = 'A test',
            uses_settings=True,
            post_statussave = save_settings
        )
        self.client.login(username='******', password='******')
        session = self.client.session
        session[create_settings_sessionkey('tst')] = {'test': 'settings'}
        session.save()
        content, response = self._postas('periodadmin', {
            'period': self.testhelper.sub_p1.id,
            'status': 'ready',
            'plugin': 'devilry_qualifiesforexam.test.plugin',
            'pluginsessionid': 'tst',
            'passing_relatedstudentids': []
        })
        self.assertEqual(response.status_code, 201)
        self.assertEqual(len(savedsettings), 2)
        self.assertEqual(savedsettings['settings'], {'test': 'settings'})
        self.assertIsInstance(savedsettings['status'], Status)


    def test_save_settings_missing_sessiondata(self):

        def save_settings(status, settings):
            pass

        qualifiesforexam_plugins.add(
            id = 'devilry_qualifiesforexam.test.plugin',
            url = '/some/url',
            title = 'Test',
            uses_settings = True,
            description = 'A test',
            post_statussave = save_settings
        )
        self.assertEquals(Status.objects.count(), 0)
        content, response = self._postas('periodadmin', {
            'period': self.testhelper.sub_p1.id,
            'status': 'ready',
            'plugin': 'devilry_qualifiesforexam.test.plugin',
            'pluginsessionid': 'tst',
            'passing_relatedstudentids': []
        })
        self.assertEqual(response.status_code, 400)
        self.assertEqual(content['detail'],
            u'The "devilry_qualifiesforexam.test.plugin"-plugin requires settings - no settings found in the session.')
        self.assertEquals(Status.objects.count(), 0) # The database rolled back because of the error


    def test_fail_verification(self):

        def post_statussave(status, settings):
            raise PluginResultsFailedVerification('Invalid')

        qualifiesforexam_plugins.add(
            id = 'devilry_qualifiesforexam.test.plugin',
            url = '/some/url',
            title = 'Test',
            description = 'A test',
            post_statussave = post_statussave
        )
        self.assertEquals(Status.objects.count(), 0)
        content, response = self._postas('periodadmin', {
            'period': self.testhelper.sub_p1.id,
            'status': 'ready',
            'plugin': 'devilry_qualifiesforexam.test.plugin',
            'pluginsessionid': 'tst',
            'passing_relatedstudentids': []
        })
        self.assertEqual(response.status_code, 400)
        self.assertEqual(content['detail'], u'Invalid')
        self.assertEquals(Status.objects.count(), 0) # The database rolled back because of the error
Esempio n. 23
0
class TestInstanceGroupRest(TestCase, GroupManagerTestMixin):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['p1'],
                            assignments=['a1:admin(a1admin)'])
        self.client = RestClient()
        self.testhelper.create_superuser('grandma')
        self.testhelper.create_user('candidate1')
        self.testhelper.create_user('examiner1')
        self.testhelper.create_superuser('superuser')
        self.a1id = self.testhelper.sub_p1_a1.id

    def _geturl(self, assignment_id, group_id):
        return '/devilry_subjectadmin/rest/group/{0}/{1}'.format(assignment_id, group_id)

    def _putas(self, username, assignment_id, group_id, data={}):
        self.client.login(username=username, password='******')
        return self.client.rest_put(self._geturl(assignment_id, group_id), data)

    def _add_group(self, name, candidates, examiners):
        self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate({candidates}):examiner({examiners})'.format(**vars()))
        return getattr(self.testhelper, 'sub_p1_a1_' + name)

    def test_put_minimal(self):
        group = self._add_group('g1', candidates='candidate1', examiners='examiner1')
        self.assertEquals(group.name, 'g1')
        self.assertEquals(group.is_open, True)
        data = {'name': 'changed',
                'is_open': False}
        content, response = self._putas('a1admin', self.a1id, group.id, data)
        self.assertEquals(response.status_code, 200)
        self.assertEquals(set(content.keys()),
                          set(['name', 'id', 'etag', 'is_open', 'parentnode',
                               'feedback', 'deadlines', 'candidates', 'tags',
                               'examiners', 'num_deliveries']))
        self.assertEquals(content['name'], 'changed')
        self.assertEquals(content['is_open'], False)
        self.assertEquals(content['parentnode'], self.a1id)
        self.assertEquals(content['num_deliveries'], 0)
        self.assertEquals(content['feedback'], None)
        self.assertEquals(content['deadlines'], [])
        self.assertEquals(content['candidates'], [])
        self.assertEquals(content['examiners'], [])
        self.assertEquals(content['tags'], [])

        groups = self.testhelper.sub_p1_a1.assignmentgroups.all()
        self.assertEquals(len(groups), 1)
        self.assertEquals(content['id'], groups[0].id)

    def _test_put_as(self, username):
        group = self._add_group('g1', candidates='candidate2', examiners='examiner2')
        data = {'name': 'changed',
                'is_open': False,
                'examiners': [self.create_examinerdict(username='******')],
                'candidates': [self.create_candidatedict(username='******')],
                'tags': [self.create_tagdict('mytag')]}
        content, response = self._putas(username, self.a1id, group.id, data)
        #from pprint import pprint
        #print 'Response content:'
        #pprint(content)
        self.assertEquals(response.status_code, 200)

        self.assertEquals(content['name'], 'changed')
        self.assertEquals(content['is_open'], False)
        self.assertEquals(content['parentnode'], self.a1id)
        self.assertEquals(content['num_deliveries'], 0)

        # Feedback
        self.assertEquals(content['feedback'], None)

        # Deadlines
        self.assertEquals(content['deadlines'], [])

        # Tags
        self.assertEquals(len(content['tags']), 1)
        tag = content['tags'][0]
        self.assertEquals(tag['tag'], 'mytag')
        self.assertEquals(set(tag.keys()), set(['id', 'tag']))

        # Examiners
        self.assertEquals(len(content['examiners']), 1)
        examiner = content['examiners'][0]
        self.assertEquals(set(examiner.keys()),
                          set(['id', 'user']))
        self.assertEquals(set(examiner['user'].keys()),
                          set(['email', 'full_name', 'id', 'username']))
        self.assertEquals(examiner['user']['id'], self.testhelper.examiner1.id)
        self.assertEquals(examiner['user']['username'], 'examiner1')

        # Candidates
        self.assertEquals(len(content['candidates']), 1)
        candidate = content['candidates'][0]
        self.assertEquals(set(candidate.keys()),
                          set(['id', 'user', 'candidate_id']))
        self.assertEquals(set(candidate['user'].keys()),
                          set(['email', 'full_name', 'id', 'username']))
        self.assertEquals(candidate['user']['id'], self.testhelper.candidate1.id)
        self.assertEquals(candidate['candidate_id'], '')
        self.assertEquals(candidate['user']['username'], 'candidate1')

        # It was actually updated?
        group = self.testhelper.sub_p1_a1.assignmentgroups.get(id=group.id)
        self.assertEquals(group.name, 'changed')

    def test_put_as_superuser(self):
        self._test_put_as('superuser')

    def test_put_as_assignmentadmin(self):
        self._test_put_as('a1admin')

    def test_put_doesnotexist(self):
        data = {'name': 'changed',
                'is_open': False}
        content, response = self._putas('grandma', 10000, 100000, data)
        self.assertEquals(response.status_code, 404)

    def test_put_denied(self):
        self.testhelper.create_user('nobody')
        self.testhelper.add_to_path('uni;sub.p1.a1.g1')
        group = self.testhelper.sub_p1_a1_g1
        data = {'name': 'changed',
                'is_open': False}
        content, response = self._putas('nobody', self.a1id, group.id, data)
        self.assertEquals(response.status_code, 403)

    def test_put_ro_fields(self):
        group = self._add_group('g1', candidates='candidate1', examiners='examiner1')
        self.assertEquals(group.name, 'g1')
        self.assertEquals(group.is_open, True)
        data = {'name': 'changed',
                'is_open': False,
                'feedback': 'should be ignored',
                'id': 'should be ignored',
                'num_deliveries': 'should be ignored',
                'deadlines': 'should be ignored'}
        content, response = self._putas('a1admin', self.a1id, group.id, data)
        self.assertEquals(response.status_code, 200)




    #
    # GET
    #
    def _getas(self, username, assignment_id, group_id):
        self.client.login(username=username, password='******')
        return self.client.rest_get(self._geturl(assignment_id, group_id))

    def _test_get_as(self, username):
        self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate(candidate1):examiner(examiner1).d1:ends(5)')
        self.testhelper.add_to_path('uni;sub.p1.a1.g1.d2:ends(10)')
        group = self.testhelper.sub_p1_a1_g1
        content, response = self._getas(username, self.a1id, group.id)
        #from pprint import pprint
        #print 'Response content:'
        #pprint(content)
        self.assertEquals(response.status_code, 200)
        self.assertEquals(set(content.keys()),
                          set(['name', 'id', 'etag', 'is_open', 'parentnode',
                               'feedback', 'deadlines', 'candidates', 'tags',
                               'examiners', 'num_deliveries']))
        self.assertEquals(content['name'], 'g1')
        self.assertEquals(content['is_open'], True)
        self.assertEquals(content['parentnode'], self.a1id)
        self.assertEquals(content['num_deliveries'], 0)
        self.assertEquals(content['feedback'], None)

        # Deadlines
        self.assertEquals(len(content['deadlines']), 2)
        self.assertEquals(set(content['deadlines'][0].keys()),
                          set(['id', 'deadline']))

        # Candidates
        self.assertEquals(len(content['candidates']), 1)
        candidate = content['candidates'][0]
        self.assertEquals(candidate['candidate_id'], None)
        self.assertEquals(candidate['user'], {'id': self.testhelper.candidate1.id,
                                              'username': '******',
                                              'email': '*****@*****.**',
                                              'full_name': None})

        # Examiners
        self.assertEquals(len(content['examiners']), 1)
        examiner = content['examiners'][0]
        self.assertEquals(examiner['user'], {'id': self.testhelper.examiner1.id,
                                              'username': '******',
                                              'email': '*****@*****.**',
                                              'full_name': None})

    def test_get_as_assignmentadmin(self):
        self._test_get_as('a1admin')

    def test_get_as_superuser(self):
        self._test_get_as('superuser')

    def test_get_denied(self):
        self.testhelper.create_user('nobody')
        self.testhelper.add_to_path('uni;sub.p1.a1.g1')
        group = self.testhelper.sub_p1_a1_g1
        content, response = self._getas('nobody', self.a1id, group.id)
        self.assertEquals(response.status_code, 403)
Esempio n. 24
0
class TestListGroupRest(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.client = RestClient()

    def _geturl(self, assignment_id):
        assignment_id = assignment_id or self.testhelper.sub_p1_a1.id
        return '/devilry_subjectadmin/rest/group/{0}/'.format(assignment_id)

    def _getas(self, username, assignment_id, **data):
        self.client.login(username=username, password='******')
        return self.client.rest_get(self._geturl(assignment_id), **data)

    def _create_testassignments(self):
        self.testhelper.add(nodes='uni',
                       subjects=['duck1010'],
                       periods=['firstsem'],
                       assignments=['a1:admin(a1admin)', 'a2'])

    def _create_testdata(self):
        self._create_testassignments()
        for num in xrange(3):
            path = 'uni;duck1010.firstsem.a1.g{num}:candidate(student{num},extrastudent):examiner(examiner1,extraexaminer).d1'
            self.testhelper.add_to_path(path.format(**vars()))
            group = getattr(self.testhelper, 'duck1010_firstsem_a1_g{0}'.format(num))
            group.tags.create(tag="stuff")
            group.tags.create(tag="lownumber")
            delivery = self.testhelper.add_delivery(group)
            if num != 2:
                self.testhelper.add_feedback(delivery,
                                             verdict=dict(grade='A', points=100,
                                                          is_passing_grade=True))

    def test_list_permissiondenied(self):
        self.testhelper.create_user('nobody')
        self._create_testassignments()
        a1 = self.testhelper.duck1010_firstsem_a1
        content, response = self._getas('nobody', a1.id)
        self.assertEquals(response.status_code, 403)


    def _test_list_as(self, username):
        self._create_testdata()
        a1 = self.testhelper.duck1010_firstsem_a1
        content, response = self._getas(username, a1.id)
        #from pprint import pprint
        #pprint(content)

        self.assertEquals(len(content), 3)
        self.assertEquals(set(content[0].keys()),
                          set(['name', 'feedback', 'deadlines', 'id', 'etag',
                               'is_open', 'parentnode', 'candidates', 'tags',
                               'examiners', 'num_deliveries']))

        # Properties directly from group
        self.assertEquals(AssignmentGroup.objects.get(id=content[0]['id']).parentnode_id,
                          a1.id)
        self.assertEquals(content[0]['is_open'], False)
        self.assertEquals(content[0]['name'], 'g0')
        self.assertEquals(content[0]['num_deliveries'], 1)
        self.assertEquals(content[0]['parentnode'], a1.id)

        # Feedback
        feedback = content[0]['feedback']
        self.assertEquals(set(feedback.keys()),
                          set(['id', 'grade', 'is_passing_grade', 'points', 'save_timestamp']))
        self.assertEquals(feedback['grade'], 'A')
        self.assertEquals(feedback['is_passing_grade'], True)
        self.assertEquals(feedback['points'], 100)

        # NULL feedback
        self.assertEquals(content[2]['feedback'], None)

        # Canididates
        def get_usernames(users):
            return [user['user']['username'] for user in users]
        self.assertEquals(len(content[0]['candidates']), 2)
        self.assertEquals(set(get_usernames(content[0]['candidates'])),
                          set(['student0', 'extrastudent']))
        self.assertEquals(set(content[0]['candidates'][0].keys()),
                          set(['id', 'candidate_id', 'user']))
        self.assertEquals(set(content[0]['candidates'][0]['user'].keys()),
                          set(['email', 'full_name', 'id', 'username']))

        # Examiners
        self.assertEquals(len(content[0]['examiners']), 2)
        self.assertEquals(set(get_usernames(content[0]['examiners'])),
                          set(['examiner1', 'extraexaminer']))
        self.assertEquals(set(content[0]['examiners'][0].keys()),
                          set(['id', 'user']))
        self.assertEquals(set(content[0]['examiners'][0]['user'].keys()),
                          set(['email', 'full_name', 'id', 'username']))

        # Deadlines
        self.assertEquals(len(content[0]['deadlines']), 1)
        deadline = content[0]['deadlines'][0]
        self.assertEquals(set(deadline.keys()),
                          set(['id', 'deadline']))

        # Tags
        self.assertEquals(len(content[0]['tags']), 2)
        tag = content[0]['tags'][0]
        self.assertEquals(set(tag.keys()),
                          set(['id', 'tag']))


    def test_list(self):
        self._test_list_as('a1admin')

    def test_list_as_superuser(self):
        self.testhelper.create_superuser('superuser')
        self._test_list_as('superuser')
class TestRestPassedInPreviousPeriod(TransactionTestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['old:begins(-14):ends(6)', # 14 months ago
                                     'cur:begins(-2)'], # 2 months ago
                            assignments=['a1:admin(adm):pub(0)']) # 0 days after period begins
        self.client = RestClient()
        self.url = '/devilry_subjectadmin/rest/passedinpreviousperiod/{0}'.format(self.testhelper.sub_cur_a1.id)

    def _getas(self, username, **data):
        self.client.login(username=username, password='******')
        return self.client.rest_get(self.url, **data)

    def _test_get_simple_as(self, username):
        self.testhelper.add_to_path('uni;sub.cur.a1.g1:candidate(student1)')
        content, response = self._getas(username)
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content), 1)
        item = content[0]
        self.assertEquals(item['group']['id'], self.testhelper.sub_cur_a1_g1.id)
        self.assertEquals(item['oldgroup'], None)
        self.assertEquals(item['whyignored'], 'not_in_previous')

    def test_get_simple_as_assignmentadmin(self):
        self._test_get_simple_as('adm')

    def test_get_simple_as_superuser(self):
        self.testhelper.create_superuser('super')
        self._test_get_simple_as('super')

    def test_get_as_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._getas('nobody')
        self.assertEquals(response.status_code, 403)


    def test_with_oldfeedback(self):
        # Add a group for the student on the old period
        self.testhelper.add_to_path('uni;sub.old.a1.g1:candidate(student1):examiner(examiner1).d1:ends(1)')
        self.testhelper.create_feedbacks(
            (self.testhelper.sub_old_a1_g1, {'grade': 'approved', 'points': 1, 'is_passing_grade': True})
        )

        # Add the student to the current period
        self.testhelper.add_to_path('uni;sub.cur.a1.g1:candidate(student1)')

        content, response = self._getas('adm')
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content), 1)
        item = content[0]
        self.assertEquals(item['group']['id'], self.testhelper.sub_cur_a1_g1.id)
        self.assertEquals(item['whyignored'], None)
        self.assertNotEquals(item['oldgroup'], None)
        oldgroup = item['oldgroup']
        self.assertEqual(oldgroup['id'], self.testhelper.sub_old_a1_g1.id)
        self.assertEqual(oldgroup['assignment']['id'], self.testhelper.sub_old_a1.id)
        self.assertEqual(oldgroup['period']['id'], self.testhelper.sub_old.id)
        self.assertEqual(oldgroup['feedback_shortformat'], 'true')



    def _putas(self, username, data):
        self.client.login(username=username, password='******')
        return self.client.rest_put(self.url, data)

    def _test_putas(self, username):
        self.testhelper.add_to_path('uni;sub.cur.a1.g1:candidate(student1).d1')
        self.testhelper.add_to_path('uni;sub.cur.a1.g2:candidate(student2).d1')
        self.testhelper.add_to_path('uni;sub.cur.a1.g3:candidate(student3).d1')

        self.testhelper.add_to_path('uni;sub.old.a1.g3:candidate(student3):examiner(examiner1).d1')
        oldg3_delivery = self.testhelper.add_delivery(self.testhelper.sub_old_a1_g3)
        self.testhelper.add_feedback(oldg3_delivery,
                                     verdict=dict(grade='C', points=40,
                                                  is_passing_grade=True))

        g1 = self.testhelper.sub_cur_a1_g1
        g2 = self.testhelper.sub_cur_a1_g2
        g3 = self.testhelper.sub_cur_a1_g3
        content, response = self._putas(username,
                                        [{'id': g1.id,
                                          'newfeedback_shortformat': 'true'},
                                         {'id': g3.id,
                                          'newfeedback_shortformat': 'true'}])
        self.assertEquals(response.status_code, 200)

        g1 = self.testhelper.reload_from_db(g1)
        self.assertEquals(g1.feedback.grade, 'approved')
        self.assertEquals(g1.feedback.delivery.delivery_type, deliverytypes.ALIAS)

        g2 = self.testhelper.reload_from_db(g2)
        self.assertEquals(g2.feedback, None)

        g3 = self.testhelper.reload_from_db(g3)
        self.assertEquals(g3.feedback.grade, 'approved')
        self.assertEquals(g3.feedback.delivery.delivery_type, deliverytypes.ALIAS)
        self.assertEquals(g3.feedback.delivery.alias_delivery, oldg3_delivery)

    def test_put_as_assignmentadmin(self):
        self._test_putas('adm')

    def test_put_as_superuser(self):
        self.testhelper.create_superuser('super')
        self._test_putas('super')

    def test_put_as_nobody(self):
        self.testhelper.create_user('nobody')
        content, response = self._putas('nobody', [])
        self.assertEquals(response.status_code, 403)


    def test_put_shortformat_validationerror(self):
        self.testhelper.add_to_path('uni;sub.cur.a1.g1:candidate(student1).d1')
        g1 = self.testhelper.sub_cur_a1_g1
        content, response = self._putas('adm',
            [{'id': g1.id,
              'newfeedback_shortformat': 'invalidstuff'}])
        self.assertEquals(response.status_code, 400)
        self.assertEquals(content['errors'][0], u'Must be one of: true, false.')
class TestRestCreateNewAssignmentDao(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['p1:admin(p1admin)', 'p2'])
        self.testhelper.create_superuser("superuser")

    def test_create_assignment(self):
        dao = CreateNewAssignmentDao()
        publishing_time = self.testhelper.sub_p1.start_time + timedelta(days=1)
        first_deadline = self.testhelper.sub_p1.start_time + timedelta(days=2)
        assignment = dao._create_assignment(period=self.testhelper.sub_p1,
                                            short_name='a1', long_name='Assignment 1',
                                            first_deadline = first_deadline,
                                            publishing_time=publishing_time,
                                            delivery_types=ELECTRONIC, anonymous=False)
        self.assertEquals(assignment.short_name, 'a1')
        self.assertEquals(assignment.long_name, 'Assignment 1')
        self.assertEquals(assignment.publishing_time, publishing_time)
        self.assertEquals(assignment.first_deadline,
                          first_deadline.replace(microsecond=0, tzinfo=None))
        self.assertEquals(assignment.delivery_types, 0)
        self.assertEquals(assignment.anonymous, False)

    def _create_related_student(self, username, candidate_id=None, tags=None):
        user = self.testhelper.create_user(username)
        relatedstudent = self.testhelper.sub_p1.relatedstudent_set.create(user=user,
                                                                          candidate_id=candidate_id)
        if tags:
            relatedstudent.tags = tags
            relatedstudent.save()
        return relatedstudent

    def _create_related_examiner(self, username, tags=None):
        user = self.testhelper.create_user(username)
        relatedexaminer = self.testhelper.sub_p1.relatedexaminer_set.create(user=user)
        if tags:
            relatedexaminer.tags = tags
            relatedexaminer.save()
        return relatedexaminer

    def test_create_group_from_relatedstudent(self):
        dao = CreateNewAssignmentDao()
        self.testhelper.add_to_path('uni;sub.p1.a1')
        related_louie = self._create_related_student('louie')
        group = dao._create_group_from_relatedstudent(self.testhelper.sub_p1_a1, related_louie, [])
        self.assertEquals(group.candidates.all()[0].student.username, 'louie')
        self.assertEquals(group.candidates.all()[0].candidate_id, None)

        related_dewey = self._create_related_student('dewey', candidate_id='dew123',
                                                     tags='bb,aa')
        related_examiner1 = self._create_related_examiner('examiner1', tags='cc,dd')
        related_examiner2 = self._create_related_examiner('examiner2', tags='aa')
        group = dao._create_group_from_relatedstudent(self.testhelper.sub_p1_a1, related_dewey,
                                                      [related_examiner1, related_examiner2])
        self.assertEquals(group.candidates.all()[0].candidate_id, 'dew123')
        self.assertEquals(group.examiners.all().count(), 1)
        tags = group.tags.all().order_by('tag')
        self.assertEquals(len(tags), 2)
        self.assertEquals(tags[0].tag, 'aa')
        self.assertEquals(tags[1].tag, 'bb')

    def test_create_group_from_relatedstudent_non_electronic(self):
        dao = CreateNewAssignmentDao()
        self.testhelper.add_to_path('uni;sub.p1.a1')
        related_louie = self._create_related_student('louie')
        a1 = self.testhelper.sub_p1_a1
        a1.delivery_types = NON_ELECTRONIC
        group = dao._create_group_from_relatedstudent(a1, related_louie, [])
        self.assertEquals(group.deadlines.count(), 1)


    def test_setupstudents_allrelated(self):
        self._create_related_student('louie')
        self._create_related_student('dewey', candidate_id='dew123')
        dao = CreateNewAssignmentDao()
        self.testhelper.add_to_path('uni;sub.p1.a1')

        self.assertEquals(self.testhelper.sub_p1_a1.assignmentgroups.count(), 0)
        deadline = self.testhelper.sub_p1_a1.publishing_time + timedelta(days=1)
        dao._setup_students(self.testhelper.sub_p1_a1,
                            first_deadline=deadline,
                            setupstudents_mode='allrelated',
                            setupexaminers_mode='do_not_setup')
        self.assertEquals(self.testhelper.sub_p1_a1.assignmentgroups.count(), 2)

        groups = list(self.testhelper.sub_p1_a1.assignmentgroups.all().order_by('candidates__student__username'))
        self.assertEquals(groups[0].candidates.all()[0].student.username, 'dewey')
        self.assertEquals(groups[0].candidates.all()[0].candidate_id, 'dew123')
        self.assertEquals(groups[1].candidates.all()[0].student.username, 'louie')
        self.assertEquals(groups[1].candidates.all()[0].candidate_id, None)

        self.assertEquals(groups[0].deadlines.all().count(), 1)
        self.assertEquals(groups[1].deadlines.all().count(), 1)
        self.assertEquals(groups[0].deadlines.all()[0].deadline, deadline)

    def test_setupstudents_allrelated_examiners_bytags(self):
        self._create_related_student('louie', tags='bb,aa')
        self._create_related_examiner('examiner2', tags='aa,cc')
        dao = CreateNewAssignmentDao()
        self.testhelper.add_to_path('uni;sub.p1.a1')

        deadline = self.testhelper.sub_p1_a1.publishing_time + timedelta(days=1)
        dao._setup_students(self.testhelper.sub_p1_a1,
                            first_deadline=deadline,
                            setupstudents_mode='allrelated',
                            setupexaminers_mode='bytags')
        group = self.testhelper.sub_p1_a1.assignmentgroups.all()[0]
        self.assertEquals(group.examiners.all().count(), 1)

    def test_setupstudents_copyfromassignment(self):
        dao = CreateNewAssignmentDao()
        self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate(student1;secret):tags(good,super)')
        self.testhelper.add_to_path('uni;sub.p1.a1.g2:candidate(student2,student3)')
        self.testhelper.add_to_path('uni;sub.p1.a2')
        deadline = self.testhelper.sub_p1_a1.publishing_time + timedelta(days=1)

        self.assertEquals(self.testhelper.sub_p1_a1.assignmentgroups.count(), 2)
        self.assertEquals(self.testhelper.sub_p1_a2.assignmentgroups.count(), 0)
        dao._setup_students(self.testhelper.sub_p1_a2,
                            first_deadline=deadline,
                            copyfromassignment_id=self.testhelper.sub_p1_a1.id,
                            setupstudents_mode='copyfromassignment',
                            setupexaminers_mode='do_not_setup')
        self.assertEquals(self.testhelper.sub_p1_a2.assignmentgroups.count(), 2)

        groups = list(self.testhelper.sub_p1_a2.assignmentgroups.all().order_by('candidates__student__username'))
        self.assertEquals(groups[0].name, 'g1')
        self.assertEquals(groups[0].candidates.all()[0].student.username, 'student1')
        self.assertEquals(groups[0].candidates.all()[0].candidate_id, 'secret')
        self.assertEquals(set([t.tag for t in groups[0].tags.all()]),
                          set(['good', 'super']))
        self.assertEquals(groups[1].name, 'g2')
        self.assertEquals(set([c.student.username for c in groups[1].candidates.all()]),
                          set(['student2', 'student3']))
        self.assertEquals(groups[1].tags.count(), 0)

        self.assertEquals(groups[0].deadlines.all().count(), 1)
        self.assertEquals(groups[1].deadlines.all().count(), 1)
        self.assertEquals(groups[0].deadlines.all()[0].deadline, deadline)

    def test_setupstudents_copyfromassignment_onlypassing(self):
        dao = CreateNewAssignmentDao()
        self.testhelper.add_to_path('uni;sub.p1.a1.awesome:candidate(student1):examiner(examiner1).d1')
        self.testhelper.add_to_path('uni;sub.p1.a1.failer:candidate(student2):examiner(examiner2).d1')
        self.testhelper.add_to_path('uni;sub.p1.a1.nofeedback:candidate(student3)')
        self.testhelper.add_delivery(self.testhelper.sub_p1_a1_awesome,
                                     {'f.py': ['print ', 'yeh']})
        self.testhelper.add_feedback(self.testhelper.sub_p1_a1_awesome,
                                     verdict={'grade': 'A', 'points': 100, 'is_passing_grade': True})
        self.testhelper.add_delivery(self.testhelper.sub_p1_a1_failer,
                                     {'f.py': ['print ', 'meh']})
        self.testhelper.add_feedback(self.testhelper.sub_p1_a1_failer,
                                     verdict={'grade': 'F', 'points': 1, 'is_passing_grade': False})

        self.testhelper.add_to_path('uni;sub.p1.a2')
        deadline = self.testhelper.sub_p1_a1.publishing_time + timedelta(days=1)
        self.assertEquals(self.testhelper.sub_p1_a1.assignmentgroups.count(), 3)
        self.assertEquals(self.testhelper.sub_p1_a2.assignmentgroups.count(), 0)

        dao._setup_students(self.testhelper.sub_p1_a2,
                            first_deadline=deadline,
                            copyfromassignment_id=self.testhelper.sub_p1_a1.id,
                            only_copy_passing_groups=True,
                            setupstudents_mode='copyfromassignment',
                            setupexaminers_mode='do_not_setup')
        self.assertEquals(self.testhelper.sub_p1_a2.assignmentgroups.count(), 1)

        group = self.testhelper.sub_p1_a2.assignmentgroups.all()[0]
        self.assertEquals(group.name, 'awesome')

    def test_setupstudents_copyfromassignment_withexaminers(self):
        dao = CreateNewAssignmentDao()
        self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate(student1):examiner(examiner1,examiner2)')
        self.testhelper.add_to_path('uni;sub.p1.a2')
        deadline = self.testhelper.sub_p1_a1.publishing_time + timedelta(days=1)

        dao._setup_students(self.testhelper.sub_p1_a2,
                            first_deadline=deadline,
                            copyfromassignment_id=self.testhelper.sub_p1_a1.id,
                            setupstudents_mode='copyfromassignment',
                            setupexaminers_mode='copyfromassignment')
        self.assertEquals(self.testhelper.sub_p1_a2.assignmentgroups.count(), 1)

        group = self.testhelper.sub_p1_a2.assignmentgroups.all()[0]
        self.assertEquals(set([c.user.username for c in group.examiners.all()]),
                          set(['examiner1', 'examiner2']))

    def test_setupstudents_copyfromassignment_outofperiod(self):
        dao = CreateNewAssignmentDao()
        self.testhelper.add_to_path('uni;sub.p1.a1')
        self.testhelper.add_to_path('uni;sub.p2.a1')
        deadline = self.testhelper.sub_p1_a1.publishing_time + timedelta(days=1)

        with self.assertRaises(BadRequestFieldError):
            dao._setup_students(self.testhelper.sub_p1_a1,
                                first_deadline=deadline,
                                copyfromassignment_id=self.testhelper.sub_p2_a1.id,
                                setupstudents_mode='copyfromassignment',
                                setupexaminers_mode='copyfromassignment')

    def test_setupstudents_copyfromassignment_make_authuser_examiner(self):
        dao = CreateNewAssignmentDao()
        self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate(student1)')
        self.testhelper.add_to_path('uni;sub.p1.a2')
        deadline = self.testhelper.sub_p1_a1.publishing_time + timedelta(days=1)

        user = self.testhelper.create_user('superhero')
        dao._setup_students(self.testhelper.sub_p1_a2,
                            first_deadline=deadline,
                            copyfromassignment_id=self.testhelper.sub_p1_a1.id,
                            setupstudents_mode='copyfromassignment',
                            setupexaminers_mode='make_authenticated_user_examiner',
                            user=user)
        self.assertEquals(self.testhelper.sub_p1_a2.assignmentgroups.count(), 1)

        group = self.testhelper.sub_p1_a2.assignmentgroups.all()[0]
        self.assertEquals(set([c.user.username for c in group.examiners.all()]),
                          set(['superhero']))
Esempio n. 27
0
class TestRestInstanceAssignmentRest(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni:admin(uniadmin)',
                            subjects=['duck2000:admin(duck2000admin)'],
                            periods=['someperiod:begins(-2):ends(6)'],
                            assignments=['first:admin(firstadmin)',
                                         'second:admin(secondadmin,firstadmin)',
                                         'third'])
        self.client = RestClient()

    def _geturl(self, assignmentid):
        return '/devilry_subjectadmin/rest/assignment/{0}'.format(assignmentid)

    def test_delete_denied(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_delete(self._geturl(self.testhelper.duck2000_someperiod_first.id))
        self.assertEquals(response.status_code, 403)

    def test_delete(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_delete(self._geturl(self.testhelper.duck2000_someperiod_first.id))
        self.assertEquals(response.status_code, 200)
        self.assertEquals(content['id'], self.testhelper.duck2000_someperiod_first.id)
        self.assertEquals(Assignment.objects.filter(id=self.testhelper.duck2000_someperiod_first.id).count(), 0)

    def test_get(self):
        self.testhelper.add_to_path('uni;duck2000.someperiod.first.g1:candidate(student1):examiner(examiner1).d1')
        self.testhelper.add_to_path('uni;duck2000.someperiod.first.g2:candidate(student2,student3,student4,student5):examiner(examiner1).d1')
        self.testhelper.add_delivery('duck2000.someperiod.first.g1', {'bad.py': ['print ', 'bah']})
        self.testhelper.add_delivery('duck2000.someperiod.first.g1', {'good.py': ['print ', 'good']})
        self.testhelper.add_delivery('duck2000.someperiod.first.g2', {'good.py': ['print ', 'good']})

        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.duck2000_someperiod_first.id))
        self.assertEquals(response.status_code, 200)
        self.assertEquals(content['id'], self.testhelper.duck2000_someperiod_first.id)
        self.assertEquals(content['short_name'], self.testhelper.duck2000_someperiod_first.short_name)
        self.assertEquals(content['long_name'], self.testhelper.duck2000_someperiod_first.long_name)
        self.assertEquals(content['deadline_handling'], self.testhelper.duck2000_someperiod_first.deadline_handling)
        self.assertEquals(content['parentnode'], self.testhelper.duck2000_someperiod_first.parentnode_id)
        self.assertEquals(content['can_delete'], self.testhelper.duck2000_someperiod_first.can_delete(self.testhelper.duck2000admin))
        self.assertEquals(content['can_delete'], False)
        self.assertEquals(content['number_of_groups'], 2)
        self.assertEquals(content['number_of_deliveries'], 3)
        self.assertEquals(content['number_of_candidates'], 5)
        self.assertEquals(content['has_valid_grading_setup'], True)
        self.assertEquals(content['gradingsystemplugin_title'], 'Passed/failed')
        self.assertEquals(set(content.keys()),
                          set(['short_name', 'long_name', 'admins', 'etag',
                               'can_delete', 'parentnode', 'id', 'inherited_admins',
                               'publishing_time', 'delivery_types',
                               'is_published', 'publishing_time_offset_from_now',
                               'scale_points_percent', 'deadline_handling',
                               'first_deadline', 'breadcrumb', 'anonymous',
                               'number_of_deliveries', 'number_of_groups',
                               'number_of_candidates',
                               'number_of_groups_where_is_examiner',
                               'has_valid_grading_setup', 'gradingsystemplugin_title',
                               'max_points', 'points_to_grade_mapper', 'grading_system_plugin_id', 'passing_grade_min_points'
                               ]))

    def test_get_admins(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.duck2000_someperiod_first.id))
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content['admins']), 1)
        self.assertEquals(content['admins'][0]['email'], '*****@*****.**')
        self.assertEquals(set(content['admins'][0].keys()),
                          set(['email', 'username', 'id', 'full_name']))

    def test_get_inherited_admins(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.duck2000_someperiod_first.id))
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content['inherited_admins']), 2)
        self.assertEquals(set(content['inherited_admins'][0].keys()),
                          set(['basenode', 'user']))
        self.assertEquals(set(content['inherited_admins'][0]['basenode'].keys()),
                          set(['type', 'path', 'id', 'is_admin']))
        self.assertEquals(set(content['inherited_admins'][0]['user'].keys()),
                          set(['email', 'username', 'id', 'full_name']))
        inherited_adminusernames = [user['user']['username'] for user in content['inherited_admins']]
        self.assertIn('uniadmin', inherited_adminusernames)
        self.assertIn('duck2000admin', inherited_adminusernames)

    def test_get_breadcrumb_assignmentadmin(self):
        self.testhelper.add(nodes='uni.inf',
                            subjects=['sub'],
                            periods=['p1'],
                            assignments=['a1:admin(a1admin)'])
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.sub_p1_a1.id))
        self.assertEquals(response.status_code, 200)
        th = self.testhelper
        self.assertEquals(content['breadcrumb'],
                          [{u'id': th.sub_p1_a1.id, u'text': u'sub.p1.a1', u'type': u'Assignment'}])

    def test_get_breadcrumb_periodadmin(self):
        self.testhelper.add(nodes='uni.inf',
                            subjects=['sub'],
                            periods=['p1:admin(p1admin)'],
                            assignments=['a1'])
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.sub_p1_a1.id))
        self.assertEquals(response.status_code, 200)
        th = self.testhelper
        self.assertEquals(content['breadcrumb'],
                          [{u'id': th.sub_p1.id, u'text': u'sub.p1', u'type': u'Period'},
                           {u'id': th.sub_p1_a1.id, u'text': u'a1', u'type': u'Assignment'}])

    def test_get_breadcrumb_subjectadmin(self):
        self.testhelper.add(nodes='uni.inf',
                            subjects=['sub:admin(subadm)'],
                            periods=['p1'],
                            assignments=['a1'])
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.sub_p1_a1.id))
        self.assertEquals(response.status_code, 200)
        th = self.testhelper
        self.assertEquals(content['breadcrumb'],
                          [{u'id': th.sub.id, u'text': u'sub', u'type': u'Subject'},
                           {u'id': th.sub_p1.id, u'text': u'p1', u'type': u'Period'},
                           {u'id': th.sub_p1_a1.id, u'text': u'a1', u'type': u'Assignment'}])

    def test_get_breadcrumb_nodeadmin(self):
        self.testhelper.add(nodes='uni:admin(uniadm).inf',
                            subjects=['sub'],
                            periods=['p1'],
                            assignments=['a1'])
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.sub_p1_a1.id))
        self.assertEquals(response.status_code, 200)
        th = self.testhelper
        self.assertEquals(content['breadcrumb'],
                          [{u'id': th.uni.id, u'text': u'uni', u'type': u'Node'},
                           {u'id': th.uni_inf.id, u'text': u'inf', u'type': u'Node'},
                           {u'id': th.sub.id, u'text': u'sub', u'type': u'Subject'},
                           {u'id': th.sub_p1.id, u'text': u'p1', u'type': u'Period'},
                           {u'id': th.sub_p1_a1.id, u'text': u'a1', u'type': u'Assignment'}])

    def test_get_breadcrumb_superuser(self):
        self.testhelper.add(nodes='uni.inf',
                            subjects=['sub'],
                            periods=['p1'],
                            assignments=['a1'])
        self.testhelper.create_superuser('super')
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.sub_p1_a1.id))
        self.assertEquals(response.status_code, 200)
        th = self.testhelper
        self.assertEquals(content['breadcrumb'],
                          [{u'id': th.uni.id, u'text': u'uni', u'type': u'Node'},
                           {u'id': th.uni_inf.id, u'text': u'inf', u'type': u'Node'},
                           {u'id': th.sub.id, u'text': u'sub', u'type': u'Subject'},
                           {u'id': th.sub_p1.id, u'text': u'p1', u'type': u'Period'},
                           {u'id': th.sub_p1_a1.id, u'text': u'a1', u'type': u'Assignment'}])

    def test_get_can_not_delete(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.duck2000_someperiod_first.id))
        self.assertEquals(response.status_code, 200)
        self.assertFalse(content['can_delete'])

    def test_put(self):
        self.client.login(username='******', password='******')
        data = {'short_name': 'duck2000',
                'long_name': 'Updated',
                'admins': [],
                'publishing_time': isoformat_relativetime(days=-2),
                'scale_points_percent': 80,
                'deadline_handling': 0,
                'delivery_types': 0,
                'parentnode': 1}
        content, response = self.client.rest_put(self._geturl(self.testhelper.duck2000_someperiod_first.id),
                                                 data=data)
        self.assertEquals(response.status_code, 200)
        self.assertEquals(content['id'], self.testhelper.duck2000_someperiod_first.id)
        self.assertEquals(content['short_name'], self.testhelper.duck2000.short_name)
        self.assertEquals(content['long_name'], 'Updated')
        self.assertEquals(content['parentnode'], 1)
        self.assertEquals(content['scale_points_percent'], 80)
        self.assertEquals(content['deadline_handling'], 0)
        self.assertEquals(content['delivery_types'], 0)
        self.assertEquals(set(content.keys()),
                          set(['short_name', 'long_name', 'admins', 'etag',
                               'can_delete', 'parentnode', 'id', 'inherited_admins',
                               'publishing_time', 'delivery_types',
                               'is_published', 'publishing_time_offset_from_now',
                               'scale_points_percent', 'deadline_handling',
                               'first_deadline', 'breadcrumb', 'anonymous',
                               'number_of_deliveries', 'number_of_groups',
                               'number_of_candidates',
                               'number_of_groups_where_is_examiner',
                               'has_valid_grading_setup', 'gradingsystemplugin_title',
                               'max_points', 'points_to_grade_mapper', 'grading_system_plugin_id', 'passing_grade_min_points'
                               ]))
        updated = Assignment.objects.get(id=self.testhelper.duck2000_someperiod_first.id)
        self.assertEquals(updated.long_name, 'Updated')

    def test_put_admins(self):
        self.client.login(username='******', password='******')
        self.testhelper.create_user('user1')
        self.testhelper.create_user('user2')
        self.testhelper.create_user('user3')
        data = {'short_name': 'duck2000',
                'long_name': 'Updated',
                'admins': [{'username': '******',
                             'email': 'ignored',
                             'full_name': 'ignored!'},
                           {'username': '******'},
                           {'id': self.testhelper.user3.id}],
                'publishing_time': isoformat_relativetime(days=-2),
                'scale_points_percent': 80,
                'deadline_handling': 0,
                'delivery_types': 0,
                'parentnode': 1}
        content, response = self.client.rest_put(self._geturl(self.testhelper.duck2000_someperiod_first.id),
                                                 data=data)
        self.assertEquals(response.status_code, 200)
        admins = content['admins']
        self.assertEquals(len(content['admins']), 3)
        admins.sort(cmp=lambda a,b: cmp(a['username'], b['username']))
        self.assertEquals(admins[0]['username'], 'user1')
        self.assertEquals(admins[2]['username'], 'user3')
        updated = Assignment.objects.get(id=self.testhelper.duck2000_someperiod_first.id)
        self.assertEquals(updated.admins.all().count(), 3)
class TestRestNodeDetails(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni:admin(uniadmin).inf:admin(infadmin)')
        self.testhelper.add(nodes='uni.fys')
        self.testhelper.create_superuser('super')
        self.client = RestClient()

    def _geturl(self, node_id):
        return reverse('devilry_nodeadmin-rest_node_details', kwargs={'id': node_id})

    def test_as_nobody(self):
        self.testhelper.create_user('nobody')
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.uni_inf.id))
        self.assertEquals(response.status_code, 403)

    def test_as_wrongadmin(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.uni_fys.id))
        self.assertEquals(response.status_code, 403)

    def _test_get_as(self, username):
        self.client.login(username=username, password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.uni_inf.id))
        self.assertEquals(response.status_code, 200)
        self.assertEquals(set(content.keys()),
                set([u'subject_count', u'short_name', u'id',
                    u'long_name', u'assignment_count', u'etag',
                    u'period_count', u'path', u'childnodes', u'subjects']))
        self.assertEquals(content['short_name'], 'inf')
        self.assertEquals(content['id'], self.testhelper.uni_inf.id)

    def test_get_as_nodeadmin(self):
        self._test_get_as('infadmin')

    def test_get_as_superuser(self):
        self._test_get_as('super')


    def test_get_path_only_admin_on_child(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.uni_inf.id))
        self.assertEquals(response.status_code, 200)
        self.assertEquals(content['path'], [
            {u'id': self.testhelper.uni_inf.id, u'short_name': u'uni.inf'}
        ])

    def _test_get_path_toplevel_admin(self, username):
        self.client.login(username=username, password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.uni_inf.id))
        self.assertEquals(response.status_code, 200)
        self.assertEquals(content['path'], [
            {u'id': self.testhelper.uni.id, u'short_name': u'uni'},
            {u'id': self.testhelper.uni_inf.id, u'short_name': u'inf'}
        ])

    def test_get_path_toplevel_admin(self):
        self._test_get_path_toplevel_admin('uniadmin')

    def test_get_path_toplevel_superuser(self):
        self._test_get_path_toplevel_admin('super')
Esempio n. 29
0
class TestCreateGroupRest(TestCase, GroupManagerTestMixin):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['p1'],
                            assignments=['a1:admin(a1admin)'])
        self.client = RestClient()
        self.testhelper.create_user('candidate1')
        self.testhelper.create_user('examiner1')
        self.testhelper.create_superuser('grandma')
        self.a1id = self.testhelper.sub_p1_a1.id

    def _geturl(self, assignment_id):
        return '/devilry_subjectadmin/rest/group/{0}/'.format(assignment_id)

    def _postas(self, username, assignment_id, data={}):
        self.client.login(username=username, password='******')
        return self.client.rest_post(self._geturl(assignment_id), data)

    def test_create_minimal(self):
        data = {'name': 'g1',
                'is_open': False}
        content, response = self._postas('a1admin', self.a1id, data)
        self.assertEquals(response.status_code, 201)
        self.assertEquals(set(content.keys()),
                          set(['name', 'id', 'etag', 'is_open', 'parentnode',
                               'feedback', 'deadlines', 'candidates', 'tags',
                               'examiners', 'num_deliveries']))
        self.assertEquals(content['name'], 'g1')
        self.assertEquals(content['is_open'], False)
        self.assertEquals(content['parentnode'], self.a1id)
        self.assertEquals(content['num_deliveries'], 0)
        self.assertEquals(content['feedback'], None)
        self.assertEquals(content['deadlines'], [])
        self.assertEquals(content['candidates'], [])
        self.assertEquals(content['examiners'], [])
        self.assertEquals(content['tags'], [])

        groups = self.testhelper.sub_p1_a1.assignmentgroups.all()
        self.assertEquals(len(groups), 1)
        self.assertEquals(content['id'], groups[0].id)


    def _test_create_as(self, username):
        data = {'name': 'g1',
                'is_open': False,
                'examiners': [self.create_examinerdict(username='******')],
                'candidates': [self.create_candidatedict(username='******')],
                'tags': [self.create_tagdict('mytag')]}
        content, response = self._postas(username, self.a1id, data)
        #from pprint import pprint
        #print 'Response content:'
        #pprint(content)
        self.assertEquals(response.status_code, 201)


        self.assertEquals(content['name'], 'g1')
        self.assertEquals(content['is_open'], False)
        self.assertEquals(content['parentnode'], self.a1id)
        self.assertEquals(content['num_deliveries'], 0)

        # Feedback
        self.assertEquals(content['feedback'], None)

        # Deadlines
        self.assertEquals(content['deadlines'], [])

        # Tags
        self.assertEquals(len(content['tags']), 1)
        tag = content['tags'][0]
        self.assertEquals(tag['tag'], 'mytag')
        self.assertEquals(set(tag.keys()), set(['id', 'tag']))

        # Examiners
        self.assertEquals(len(content['examiners']), 1)
        examiner = content['examiners'][0]
        self.assertEquals(set(examiner.keys()),
                          set(['id', 'user']))
        self.assertEquals(set(examiner['user'].keys()),
                          set(['email', 'full_name', 'id', 'username']))
        self.assertEquals(examiner['user']['id'], self.testhelper.examiner1.id)
        self.assertEquals(examiner['user']['username'], 'examiner1')

        # Candidates
        self.assertEquals(len(content['candidates']), 1)
        candidate = content['candidates'][0]
        self.assertEquals(set(candidate.keys()),
                          set(['id', 'user', 'candidate_id']))
        self.assertEquals(set(candidate['user'].keys()),
                          set(['email', 'full_name', 'id', 'username']))
        self.assertEquals(candidate['user']['id'], self.testhelper.candidate1.id)
        self.assertEquals(candidate['candidate_id'], '')
        self.assertEquals(candidate['user']['username'], 'candidate1')

        # It was actually created?
        groups = self.testhelper.sub_p1_a1.assignmentgroups.all()
        self.assertEquals(len(groups), 1)
        self.assertEquals(content['id'], groups[0].id)

    def test_create_as_assignmentadmin(self):
        self._test_create_as('a1admin')

    def test_create_as_superuser(self):
        self._test_create_as('grandma')

    def test_noperm(self):
        self.testhelper.create_user('nobody')
        data = {'name': 'g1',
                'is_open': False}
        content, response = self._postas('nobody', self.a1id, data)
        self.assertEquals(response.status_code, 403)
        self.assertEquals(content, {u'detail': u'Permission denied'})

    def test_create_ro_fields(self):
        data = {'name': 'g1',
                'is_open': False,
                'id': 'should be ignored',
                'feedback': 'should be ignored',
                'num_deliveries': 'should be ignored',
                'deadlines': 'should be ignored'}
        content, response = self._postas('a1admin', self.a1id, data)
        self.assertEquals(response.status_code, 201)
class TestRestInstancePeriodRest(TestCase):
    def setUp(self):
        self.testhelper = TestHelper()
        self.testhelper.add(nodes='uni:admin(uniadmin)',
                            subjects=['duck2000:admin(duck2000admin)'],
                            periods=['periodone:admin(oneadmin)',
                                     'periodtwo',
                                     'periodthree:admin(adminone)'])
        self.client = RestClient()

    def _geturl(self, periodid):
        return '/devilry_subjectadmin/rest/period/{0}'.format(periodid)

    def test_delete_denied(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_delete(self._geturl(self.testhelper.duck2000_periodone.id))
        self.assertEquals(response.status_code, 403)

    def test_delete(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_delete(self._geturl(self.testhelper.duck2000_periodone.id))
        self.assertEquals(response.status_code, 200)
        self.assertEquals(content['id'], self.testhelper.duck2000_periodone.id)
        self.assertEquals(Period.objects.filter(id=self.testhelper.duck2000_periodone.id).count(), 0)


    def test_get(self):
        period = self.testhelper.duck2000_periodone
        for username in ('student1', 'student2', 'student3', 'student4'):
            user = self.testhelper.create_user(username)
            period.relatedstudent_set.create(user=user)
        for username in ('examiner1', 'examiner2'):
            user = self.testhelper.create_user(username)
            period.relatedexaminer_set.create(user=user)

        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.duck2000_periodone.id))
        self.assertEquals(response.status_code, 200)
        self.assertEquals(content['id'], self.testhelper.duck2000_periodone.id)
        self.assertEquals(content['short_name'], self.testhelper.duck2000_periodone.short_name)
        self.assertEquals(content['long_name'], self.testhelper.duck2000_periodone.long_name)
        self.assertEquals(content['parentnode'], self.testhelper.duck2000_periodone.parentnode_id)
        self.assertEquals(content['can_delete'], self.testhelper.duck2000_periodone.can_delete(self.testhelper.uniadmin))
        self.assertEquals(content['number_of_relatedexaminers'], 2)
        self.assertEquals(content['number_of_relatedstudents'], 4)
        self.assertEquals(set(content.keys()),
                          set(['short_name', 'long_name', 'admins', 'etag',
                               'can_delete', 'parentnode', 'id', 'inherited_admins',
                               'start_time', 'end_time', 'breadcrumb',
                               'number_of_relatedexaminers', 'number_of_relatedstudents']))

    def test_get_admins(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.duck2000_periodone.id))
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content['admins']), 1)
        self.assertEquals(content['admins'][0]['email'], '*****@*****.**')
        self.assertEquals(set(content['admins'][0].keys()),
                          set(['email', 'username', 'id', 'full_name']))

    def test_get_inherited_admins(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.duck2000_periodone.id))
        self.assertEquals(response.status_code, 200)
        self.assertEquals(len(content['inherited_admins']), 2)
        self.assertEquals(set(content['inherited_admins'][0].keys()),
                          set(['basenode', 'user']))
        self.assertEquals(set(content['inherited_admins'][0]['basenode'].keys()),
                          set(['type', 'path', 'id', 'is_admin']))
        self.assertEquals(set(content['inherited_admins'][0]['user'].keys()),
                          set(['email', 'username', 'id', 'full_name']))
        inherited_adminusernames = [user['user']['username'] for user in content['inherited_admins']]
        self.assertIn('uniadmin', inherited_adminusernames)
        self.assertIn('duck2000admin', inherited_adminusernames)

    def test_get_breadcrumb_periodadmin(self):
        self.testhelper.add(nodes='uni',
                            subjects=['sub'],
                            periods=['p1:admin(p1admin)'])
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.sub_p1.id))
        self.assertEquals(response.status_code, 200)
        th = self.testhelper
        self.assertEquals(content['breadcrumb'],
                          [{u'id': th.sub_p1.id, u'text': u'sub.p1', u'type': u'Period'}])

    def test_get_breadcrumb_subjectadmin(self):
        self.testhelper.add(nodes='uni',
                            subjects=['sub:admin(subadm)'],
                            periods=['p1'])
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.sub_p1.id))
        self.assertEquals(response.status_code, 200)
        th = self.testhelper
        self.assertEquals(content['breadcrumb'],
                          [{u'id': th.sub.id, u'text': u'sub', u'type': u'Subject'},
                           {u'id': th.sub_p1.id, u'text': u'p1', u'type': u'Period'}])

    def test_get_breadcrumb_nodeadmin(self):
        self.testhelper.add(nodes='uni:admin(uniadmin).inf',
                            subjects=['sub'],
                            periods=['p1'])
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.sub_p1.id))
        self.assertEquals(response.status_code, 200)
        th = self.testhelper
        self.assertEquals(content['breadcrumb'],
                          [{u'id': th.uni.id, u'text': u'uni', u'type': u'Node'},
                           {u'id': th.uni_inf.id, u'text': u'inf', u'type': u'Node'},
                           {u'id': th.sub.id, u'text': u'sub', u'type': u'Subject'},
                           {u'id': th.sub_p1.id, u'text': u'p1', u'type': u'Period'}])

    def test_get_breadcrumb_superuser(self):
        self.testhelper.add(nodes='uni.inf',
                            subjects=['sub'],
                            periods=['p1'])
        self.testhelper.create_superuser('super')
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.sub_p1.id))
        self.assertEquals(response.status_code, 200)
        th = self.testhelper
        self.assertEquals(content['breadcrumb'],
                          [{u'id': th.uni.id, u'text': u'uni', u'type': u'Node'},
                           {u'id': th.uni_inf.id, u'text': u'inf', u'type': u'Node'},
                           {u'id': th.sub.id, u'text': u'sub', u'type': u'Subject'},
                           {u'id': th.sub_p1.id, u'text': u'p1', u'type': u'Period'}])

    def test_get_can_not_delete(self):
        self.client.login(username='******', password='******')
        content, response = self.client.rest_get(self._geturl(self.testhelper.duck2000_periodone.id))
        self.assertFalse(content['can_delete'])

    def test_put(self):
        self.client.login(username='******', password='******')
        data = {'short_name': 'duck2000',
                'long_name': 'Updated',
                'admins': [],
                'start_time': isoformat_relativetime(days=-2),
                'end_time': isoformat_relativetime(days=2),
                'parentnode': 1}
        content, response = self.client.rest_put(self._geturl(self.testhelper.duck2000_periodone.id),
                                                 data=data)
        self.assertEquals(response.status_code, 200)
        self.assertEquals(content['id'], self.testhelper.duck2000_periodone.id)
        self.assertEquals(content['short_name'], self.testhelper.duck2000.short_name)
        self.assertEquals(content['long_name'], 'Updated')
        self.assertEquals(content['parentnode'], 1)
        self.assertEquals(set(content.keys()),
                          set(['short_name', 'long_name', 'admins', 'etag',
                               'can_delete', 'parentnode', 'id', 'inherited_admins',
                               'start_time', 'end_time', 'breadcrumb',
                               'number_of_relatedstudents', 'number_of_relatedexaminers']))
        updated = Period.objects.get(id=self.testhelper.duck2000_periodone.id)
        self.assertEquals(updated.long_name, 'Updated')

    def test_put_admins(self):
        self.client.login(username='******', password='******')
        self.testhelper.create_user('user1')
        self.testhelper.create_user('user2')
        self.testhelper.create_user('user3')
        data = {'short_name': 'duck2000',
                'long_name': 'Updated',
                'admins': [{'username': '******',
                             'email': 'ignored',
                             'full_name': 'ignored!'},
                           {'username': '******'},
                           {'id': self.testhelper.user3.id}],
                'start_time': isoformat_relativetime(days=-2),
                'end_time': isoformat_relativetime(days=2),
                'parentnode': 1}
        content, response = self.client.rest_put(self._geturl(self.testhelper.duck2000_periodone.id),
                                                 data=data)
        self.assertEquals(response.status_code, 200)
        admins = content['admins']
        self.assertEquals(len(content['admins']), 3)
        admins.sort(cmp=lambda a,b: cmp(a['username'], b['username']))
        self.assertEquals(admins[0]['username'], 'user1')
        self.assertEquals(admins[2]['username'], 'user3')
        updated = Period.objects.get(id=self.testhelper.duck2000_periodone.id)
        self.assertEquals(updated.admins.all().count(), 3)