class TestManageMultipleStudentsMixin(object): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['p1'], assignments=['a1:admin(a1admin)']) self.assignment = self.testhelper.sub_p1_a1 def browseToAndSelectAs(self, username, select_groups=[]): select_ids = ','.join([str(group.id) for group in select_groups]) path = '/assignment/{0}/@@manage-students/@@select/{1}'.format(self.assignment.id, select_ids) self.loginTo(username, path) self.waitForCssSelector('.devilry_subjectadmin_multiplegroupsview') def create_group(self, groupspec): self.testhelper.add_to_path('uni;sub.p1.a1.{0}'.format(groupspec)) groupname = groupspec.split('.')[0].split(':')[0] return getattr(self.testhelper, 'sub_p1_a1_{0}'.format(groupname)) def find_element(self, cssselector): return self.selenium.find_element_by_css_selector('.devilry_subjectadmin_multiplegroupsview {0}'.format(cssselector)) def find_elements(self, cssselector): return self.selenium.find_elements_by_css_selector('.devilry_subjectadmin_multiplegroupsview {0}'.format(cssselector))
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('/'))
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)
class TestManageSingleGroupMixin(object): DELIVERY_TYPES = 'electronic' def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['p1:begins(-2):ends(6)'], assignments=['a1:admin(a1admin):delivery_types({0})'.format(self.DELIVERY_TYPES)]) self.assignment = self.testhelper.sub_p1_a1 def browseToAndSelectAs(self, username, select_group): path = '/assignment/{0}/@@manage-students/@@select/{1}'.format(self.assignment.id, select_group.id) self.loginTo(username, path) return self.waitForAndFindElementByCssSelector('.devilry_subjectadmin_singlegroupview') def create_group(self, groupspec): self.testhelper.add_to_path('uni;sub.p1.a1.{0}'.format(groupspec)) groupname = groupspec.split('.')[0].split(':')[0] return getattr(self.testhelper, 'sub_p1_a1_{0}'.format(groupname)) def find_element(self, cssselector): return self.selenium.find_element_by_css_selector('.devilry_subjectadmin_singlegroupview {0}'.format(cssselector)) def find_elements(self, cssselector): return self.selenium.find_elements_by_css_selector('.devilry_subjectadmin_singlegroupview {0}'.format(cssselector)) def find_listofgroups_rows(self, selected_only=False): cssselector = '.devilry_subjectadmin_listofgroups .x-grid-row' if selected_only: cssselector += '-selected' return self.selenium.find_elements_by_css_selector(cssselector)
class TestEditPublishingTime(SubjectAdminSeleniumTestCase): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['period1:begins(-3)'], assignments=['week1:admin(week1admin)']) self.login('week1admin') self.browseTo('/assignment/1/') self.waitForCssSelector('.devilry_subjectadmin_editpublishingtime_widget .edit_link') button = self.selenium.find_element_by_css_selector('.devilry_subjectadmin_editpublishingtime_widget .edit_link') button.click() self.waitForCssSelector('.devilry_subjectadmin_editpublishingtime') editpublishingtime_window = self.selenium.find_element_by_css_selector('.devilry_subjectadmin_editpublishingtime') self.datefield = editpublishingtime_window.find_element_by_css_selector('.devilry_extjsextras_datefield input') self.timefield = editpublishingtime_window.find_element_by_css_selector('.devilry_extjsextras_timefield input') self.savebutton = editpublishingtime_window.find_element_by_css_selector('.devilry_extjsextras_savebutton button') self.cancelbutton = editpublishingtime_window.find_element_by_css_selector('.devilry_extjsextras_cancelbutton') self.editpublishingtime_window = editpublishingtime_window def _set_datetime(self, date, time): self.datefield.clear() self.timefield.clear() self.datefield.send_keys(date) self.timefield.send_keys(time) def test_editpublishingtime(self): self.assertTrue('Publishing time' in self.selenium.page_source) self.assertTrue('Choose a time when time when students will be able to start adding deliveries on the assignment' in self.selenium.page_source) now = datetime.now() yesterday = now - timedelta(days=1) isoday_yesterday = yesterday.date().isoformat() self._set_datetime(isoday_yesterday, '12:00') self.savebutton.click() self.waitForText('{isoday_yesterday} 12:00'.format(**vars())) # If this times out, it has not been updated week1 = Assignment.objects.get(pk=self.testhelper.sub_period1_week1.pk) self.assertEquals(week1.publishing_time.date(), yesterday.date()) def test_editpublishingtime_notpublished(self): tomorrow = datetime.now() + timedelta(days=1) isoday_tomorrow = tomorrow.date().isoformat() self._set_datetime(isoday_tomorrow, '12:00') self.savebutton.click() self.waitForText('{isoday_tomorrow} 12:00'.format(**vars())) # If this times out, it has not been updated week1 = Assignment.objects.get(pk=self.testhelper.sub_period1_week1.pk) self.assertEquals(week1.publishing_time.date(), tomorrow.date()) def test_cancel(self): self.failIfCssSelectorFound(self.editpublishingtime_window, '.x-tool-close') # Make sure window does not have closable set to true self.cancelbutton.click() self.assertFalse('.devilry_subjectadmin_editpublishingtime' in self.selenium.page_source) def test_editpublishingtime_errorhandling(self): self._set_datetime('2000-02-01', '12:00') self.savebutton.click() self.waitForText("The publishing time, 2000-02-01 12:00:00, is invalid")
class TestEditPublishingTime(SubjectAdminSeleniumTestCase): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['period1:begins(-3)'], assignments=['week1:admin(week1admin)']) self.week1 = self.testhelper.sub_period1_week1 self.loginTo('week1admin', '/assignment/{id}/'.format(id=self.week1.id)) self.readOnlyPanel = self.waitForAndFindElementByCssSelector('.devilry_subjectadmin_editpublishingtime_widget .markupmoreinfobox') button = self.waitForAndFindElementByCssSelector('.devilry_subjectadmin_editpublishingtime_widget .edit_link') button.click() panel = self.waitForAndFindElementByCssSelector('.devilry_subjectadmin_editpublishingtimepanel') self.datefield = panel.find_element_by_css_selector('.devilry_extjsextras_datefield input') self.timefield = panel.find_element_by_css_selector('.devilry_extjsextras_timefield input') self.savebutton = panel.find_element_by_css_selector('.okbutton button') self.cancelbutton = panel.find_element_by_css_selector('.cancelbutton button') def _set_datetime(self, date, time): self.datefield.clear() self.timefield.clear() self.datefield.send_keys(date) self.timefield.send_keys(time) def test_editpublishingtime(self): self.assertTrue('Publishing time' in self.selenium.page_source) self.assertTrue('Choose a time when students will be able to start adding deliveries on the assignment' in self.selenium.page_source) now = datetime.now() yesterday = now - timedelta(days=1) isoday_yesterday = yesterday.date().isoformat() self._set_datetime(isoday_yesterday, '12:00') self.savebutton.click() self.waitForText('{isoday_yesterday} 12:00'.format(**vars())) # If this times out, it has not been updated week1 = Assignment.objects.get(pk=self.testhelper.sub_period1_week1.pk) self.assertEquals(week1.publishing_time.date(), yesterday.date()) def test_editpublishingtime_notpublished(self): tomorrow = datetime.now() + timedelta(days=1) isoday_tomorrow = tomorrow.date().isoformat() self._set_datetime(isoday_tomorrow, '12:00') self.savebutton.click() self.waitForText('{isoday_tomorrow} 12:00'.format(**vars())) # If this times out, it has not been updated week1 = Assignment.objects.get(pk=self.testhelper.sub_period1_week1.pk) self.assertEquals(week1.publishing_time.date(), tomorrow.date()) def test_cancel(self): self.cancelbutton.click() self.waitForDisplayed(self.readOnlyPanel) def test_editpublishingtime_errorhandling(self): self._set_datetime('2000-02-01', '12:00') self.savebutton.click() self.waitForText("The publishing time, 2000-02-01 12:00:00, is invalid")
class TestRestAggregatedStudentInfo(TestCase): def setUp(self): self.testhelper = TestHelper() self.client = RestClient() self.testhelper.add(nodes='uni:admin(uniadmin)', subjects=['sub'], periods=['p1:begins(-1)'], assignments=['a1']) self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate(student1,student2):examiner(examiner1).d1:ends(5)') self.group = self.testhelper.sub_p1_a1_g1 def _get(self, user_id): return self.client.rest_get(reverse('devilry_nodeadmin-aggregatedstudentinfo', kwargs={'user_id': user_id})) def _getas(self, username, id): self.client.login(username=username, password='******') return self._get(id) def test_get(self): content, response = self._getas('uniadmin', self.testhelper.student1.id) self.assertEquals(response.status_code, 200) user = {u'username': u'student1', u'displayname': u'student1', u'id': 2, u'full_name': None, u'email': u'*****@*****.**'} self.assertEquals(content['user'], user) grouped_by_hierarky = content['grouped_by_hierarky'][0] self.assertEquals(set(grouped_by_hierarky.keys()), set([u'long_name', u'id', u'short_name', u'periods'])) period = grouped_by_hierarky['periods'][0] self.assertEquals(set(period.keys()), set([u'short_name', u'assignments', u'is_relatedstudent', u'start_time', u'is_active', u'qualified_forexams', u'long_name', u'end_time', u'id'])) assignments = period['assignments'][0] self.assertEquals(set(period.keys()), set([u'short_name', u'assignments', u'is_relatedstudent', u'start_time', u'is_active', u'qualified_forexams', u'long_name', u'end_time', u'id'])) groups = assignments['groups'][0] self.assertEquals(set(groups.keys()), set([u'status', u'active_feedback', u'id'])) def test_get_noauth(self): content, response = self._get(self.testhelper.student1.id) self.assertEquals(response.status_code, 401)
class TestRestRecentDeliveries(TestCase): def setUp(self): self.client = RestClient() self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['p1:begins(-1)'], assignments=['a1']) self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate(student1).d1') self.group = self.testhelper.sub_p1_a1_g1 self.url = '/devilry_student/rest/recent-deliveries/' def _getas(self, username): self.client.login(username=username, password='******') return self.client.rest_get(self.url) def test_nobody(self): fileinfo = {'ok.py': ['print ', 'meh']} self.testhelper.add_delivery('sub.p1.a1.g1', fileinfo) self.testhelper.create_user('nobody') content, response = self._getas('nobody') self.assertEquals(response.status_code, 200) self.assertEquals(content, []) def test_recent_deliveries_minimal(self): fileinfo = {'ok.py': ['print ', 'meh']} self.testhelper.add_delivery('sub.p1.a1.g1', fileinfo) content, response = self._getas('student1') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 1) self.assertEquals(set(content[0].keys()), set(['id', 'assignment', 'period', 'subject', 'time_of_delivery', 'group', 'number'])) assignment = self.group.parentnode period = self.group.parentnode.parentnode subject = self.group.parentnode.parentnode.parentnode self.assertEquals(content[0]['assignment'], {u'id': assignment.id, u'long_name': u'A1', u'short_name': u'a1'}) self.assertEquals(content[0]['period'], {u'id': period.id, u'long_name': u'P1', u'short_name': u'p1'}) self.assertEquals(content[0]['subject'], {u'id': subject.id, u'long_name': u'Sub', u'short_name': u'sub'}) def test_recent_deliveries_over10(self): fileinfo = {'ok.py': ['print ', 'meh']} for x in xrange(8): self.testhelper.add_delivery('sub.p1.a1.g1', fileinfo) content, response = self._getas('student1') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 6)
def handle(self, *args, **options): management.call_command('flush', verbosity=0, interactive=False) management.call_command('loaddata', 'dev_grandma', verbosity=0, interactive=False) #management.call_command('loaddata', 'dev_duckburghusers', verbosity=0, interactive=False) testhelper = TestHelper() testhelper.add(nodes="uio:admin(uioadmin).ifi:admin(ifiadmin)", subjects=["inf1100"], periods=["old:begins(-2):ends(1)", "looong"], assignments=["assignment1", "assignment2"], assignmentgroups=["g1:candidate(student1):examiner(examiner1)", "g2:examiner(examiner2)", "g3:candidate(student2,student3):examiner(examiner1,examiner2)"]) testhelper.add_to_path('uio.ifi;inf1100.looong.assignment3.group1:examiner(examiner1)') testhelper.add_to_path('uio.ifi;inf1100.old.oldassignment.group1:examiner(examiner3)')
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 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 TestRestFindGroups(TestCase): def setUp(self): self.client = RestClient() self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['p0:begins(-10):ends(2)', 'p1:begins(-1)', 'p2:begins(5)'], assignments=['a1']) self.testhelper.create_user('testuser') self.url = '/devilry_student/rest/find-groups/' def _getas(self, username, **data): self.client.login(username=username, password='******') return self.client.rest_get(self.url, **data) def test_find_groups_empty(self): content, response = self._getas('testuser') self.assertEquals(response.status_code, 200) self.assertEquals(content, []) def test_find_groups(self): # Add to the past period (should show up) self.testhelper.add_to_path('uni;sub.p0.a1.gOld:candidate(student1).d1') # Add to the active period (show show up) self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate(student1).d1') self.testhelper.add_to_path('uni;sub.p1.a1.g2:candidate(student1,student2).d1') # Add to the future period (should not show up) self.testhelper.add_to_path('uni;sub.p2.a1.gFut:candidate(student1).d1') content, response = self._getas('student1', query='sub') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 3) self.assertEquals(set(content[0].keys()), set(['id', 'name', 'assignment', 'period', 'subject'])) groupnames = set([group['name'] for group in content]) self.assertEquals(groupnames, set(['g1', 'g2', 'gOld'])) content, response = self._getas('student1', query='old') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 1) content, response = self._getas('student1', query='p1 g2') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 1) self.assertEquals(content[0]['name'], 'g2')
class TestSubjectEditAdministrators(SubjectAdminSeleniumTestCase, EditAdministratorsTestMixin, SubjectTestCommonMixin): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni:admin(uniadmin)', subjects=['duck1100']) self.login('uniadmin') def getBasenode(self): return self.testhelper.duck1100 def browseToTestBasenode(self): self.browseToSubject(self.testhelper.duck1100.id)
class TestPeriodEditAdministrators(SubjectAdminSeleniumTestCase, PeriodTestCommonMixin, EditAdministratorsTestMixin): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni:admin(uniadmin)', subjects=['sub'], periods=['p1']) self.login('uniadmin') def getBasenode(self): return self.testhelper.sub_p1 def browseToTestBasenode(self): self.browseToPeriod(self.getBasenode().id)
class TestEditDeadlineHandling(SubjectAdminSeleniumTestCase): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['period1:begins(-3)'], assignments=['week1:admin(week1admin)']) self.week1 = self.testhelper.sub_period1_week1 self.loginTo('week1admin', '/assignment/{id}/'.format(id=self.week1.id)) self.readOnlyPanel = self.waitForAndFindElementByCssSelector('.devilry_subjectadmin_editdeadline_handling_widget .containerwithedittitle') def _click_edit(self): button = self.waitForAndFindElementByCssSelector('.devilry_subjectadmin_editdeadline_handling_widget .containerwithedittitle .edit_link') button.click() editdeadline_handlingpanel = self.waitForAndFindElementByCssSelector('.devilry_subjectadmin_editdeadline_handlingpanel') self.waitForDisplayed(editdeadline_handlingpanel) self.deadline_handlingcheckbox = editdeadline_handlingpanel.find_element_by_css_selector('input.x-form-checkbox') self.savebutton = editdeadline_handlingpanel.find_element_by_css_selector('.okbutton button') self.cancelbutton = editdeadline_handlingpanel.find_element_by_css_selector('.cancelbutton button') def test_readonlypanel(self): self.assertEquals(Assignment.objects.get(pk=self.week1.pk).deadline_handling, ELECTRONIC) self.waitFor(self.readOnlyPanel, lambda p: 'Soft deadlines' in p.text) def test_editdeadline_handling(self): self._click_edit() self.assertFalse(Assignment.objects.get(pk=self.week1.pk).deadline_handling) self.deadline_handlingcheckbox.click() self.savebutton.click() self.waitFor(self.readOnlyPanel, lambda p: 'Hard deadlines' in p.text) self.assertEquals(Assignment.objects.get(pk=self.week1.pk).deadline_handling, NON_ELECTRONIC) def test_cancel(self): self._click_edit() self.cancelbutton.click() self.waitForDisplayed(self.readOnlyPanel) def test_editdeadline_handling_nochange(self): self._click_edit() self.assertEquals(Assignment.objects.get(pk=self.week1.pk).deadline_handling, ELECTRONIC) self.savebutton.click() self.waitForDisplayed(self.readOnlyPanel) self.waitForText('Soft deadlines') # If this times out, it has been updated self.assertEquals(Assignment.objects.get(pk=self.week1.pk).deadline_handling, ELECTRONIC)
class TestRestRecentFeedbacks(TestCase): def setUp(self): self.client = RestClient() self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['p1:begins(-1)'], assignments=['a1']) self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate(student1):examiner(examiner1).d1') self.group = self.testhelper.sub_p1_a1_g1 self.url = '/devilry_student/rest/recent-feedbacks/' def _getas(self, username): self.client.login(username=username, password='******') return self.client.rest_get(self.url) def test_nobody(self): fileinfo = {'ok.py': ['print ', 'meh']} self.testhelper.add_delivery('sub.p1.a1.g1', fileinfo) self.testhelper.create_user('nobody') content, response = self._getas('nobody') self.assertEquals(response.status_code, 200) self.assertEquals(content, []) def test_recent_feedbacks_minimal(self): fileinfo = {'ok.py': ['print ', 'meh']} delivery = self.testhelper.add_delivery('sub.p1.a1.g1', fileinfo) self.testhelper.add_feedback(delivery, verdict={'grade': 'F', 'points': 30, 'is_passing_grade': False}) content, response = self._getas('student1') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 1) self.assertEquals(set(content[0].keys()), set(['id', 'assignment', 'period', 'subject', 'number', 'last_feedback', 'group'])) def test_recent_deliveries_overflow(self): fileinfo = {'ok.py': ['print ', 'meh']} for x in xrange(8): delivery = self.testhelper.add_delivery('sub.p1.a1.g1', fileinfo) self.testhelper.add_feedback(delivery, verdict={'grade': '{0}/100'.format(x), 'points': x, 'is_passing_grade': False}) content, response = self._getas('student1') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 6)
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)
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 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..
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 TestEditAnonymous(SubjectAdminSeleniumTestCase): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['period1:begins(-3)'], assignments=['week1:admin(week1admin)']) self.login('week1admin') self.week1 = self.testhelper.sub_period1_week1 self.browseTo('/assignment/{0}/'.format(self.testhelper.sub_period1_week1.id)) self.waitForCssSelector('.devilry_subjectadmin_editanonymous_widget .edit_link') button = self.selenium.find_element_by_css_selector('.devilry_subjectadmin_editanonymous_widget .edit_link') button.click() self.waitForCssSelector('.devilry_subjectadmin_editanonymous') editanonymous_window = self.selenium.find_element_by_css_selector('.devilry_subjectadmin_editanonymous') self.anonymouscheckbox = editanonymous_window.find_element_by_css_selector('input.x-form-checkbox') self.savebutton = editanonymous_window.find_element_by_css_selector('.devilry_extjsextras_savebutton button') self.cancelbutton = editanonymous_window.find_element_by_css_selector('.devilry_extjsextras_cancelbutton') self.editanonymous_window = editanonymous_window def test_editanonymous(self): self.assertFalse(Assignment.objects.get(pk=self.week1.pk).anonymous) self.assertTrue('Not anonymous' in self.selenium.page_source) self.assertTrue('Examiners and students can see each other and communicate.' in self.selenium.page_source) self.anonymouscheckbox.click() self.savebutton.click() self.waitForText('>Anonymous') # If this times out, is has not been updated self.waitForText('Examiners and students can not see each other and they can not communicate.') # If this times out, is has not been updated self.assertTrue(Assignment.objects.get(pk=self.week1.pk).anonymous) def test_cancel(self): self.failIfCssSelectorFound(self.editanonymous_window, '.x-tool-close') # Make sure window does not have closable set to true self.cancelbutton.click() self.assertFalse('.devilry_subjectadmin_editanonymous' in self.selenium.page_source) def test_editanonymous_nochange(self): self.assertFalse(Assignment.objects.get(pk=self.week1.pk).anonymous) self.savebutton.click() self.waitForText('Not anonymous') # If this times out, it has not been updated self.assertFalse(Assignment.objects.get(pk=self.week1.pk).anonymous)
def handle(self, *args, **options): management.call_command("flush", verbosity=0, interactive=False) management.call_command("loaddata", "dev_grandma", verbosity=0, interactive=False) # management.call_command('loaddata', 'dev_duckburghusers', verbosity=0, interactive=False) testhelper = TestHelper() testhelper.add( nodes="uio:admin(uioadmin).ifi:admin(ifiadmin)", subjects=["inf1100"], periods=["old:begins(-2):ends(1)", "looong"], assignments=["assignment1", "assignment2"], assignmentgroups=[ "g1:candidate(student1):examiner(examiner1)", "g2:examiner(examiner2)", "g3:candidate(student2,student3):examiner(examiner1,examiner2)", ], ) testhelper.add_to_path("uio.ifi;inf1100.looong.assignment3.group1:examiner(examiner1)") testhelper.add_to_path("uio.ifi;inf1100.old.oldassignment.group1:examiner(examiner3)")
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 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 TestRestSearchStudentContent(TestCase, AssertSearchResultMixin): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni:ln(Test Uni)', subjects=['sub:ln(Test Sub)'], periods=['p1:begins(-2):ln(Test P1)'], assignments=['a1:ln(Test A1)'], assignmentgroups=[ 'TestGroup1:candidate(student1)', 'TestGroup2:candidate(student2,student1)', 'TestGroup3:candidate(student2)', 'TestGroup4:candidate(student3):examiner(student1)' ] ) self.client = RestClient() self.url = reverse('devilry_search_studentcontent') def _getas(self, username, **data): self.client.login(username=username, password='******') return self.client.rest_get(self.url, **data) def test_perms_student(self): with HaystackTestSettings(): content, response = self._getas('student1', search='Test') matches = content['matches'] self.assertEqual(len(matches), 2) self.assert_has_search_result(matches, type='core_assignmentgroup', title='Test A1', name='TestGroup1') self.assert_has_search_result(matches, type='core_assignmentgroup', title='Test A1', name='TestGroup2') def test_perms_student_unpublished(self): self.testhelper.sub_p1_a1.publishing_time = datetime.now() + timedelta(days=1) self.testhelper.sub_p1_a1.save() with HaystackTestSettings(): content, response = self._getas('student1', search='Test') matches = content['matches'] self.assertEqual(len(matches), 0)
class TestDashboardView(TestCase): def setUp(self): self.testhelper = TestHelper() def _getas(self, username, *args, **kwargs): self.client.login(username=username, password="******") return self.client.get(reverse("devilry_examiner_dashboard"), *args, **kwargs) def test_list_single(self): self.testhelper.add( nodes="uni", subjects=["sub"], periods=["period1:begins(-2)"], # 2 months ago assignments=["week2:pub(1)"], # 2 months + 1day ago assignmentgroups=["g1:candidate(student1):examiner(examiner1)"], ) response = self._getas("examiner1") self.assertEquals(response.status_code, 200) html = response.content listitems = cssFind(html, "li.active-assignment-listing-item") self.assertEquals(len(listitems), 1) self.assertEquals(listitems[0].text.strip(), "sub.period1.week2")
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)
class TestAssignmentDangerous(SubjectAdminSeleniumTestCase, RenameBasenodeTestMixin, DeleteBasenodeTestMixin): renamebutton_id = 'assignmentRenameButton' deletebutton_id = 'assignmentDeleteButton' def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni:admin(uniadmin)', subjects=['sub'], periods=['period1:begins(-2):admin(p1admin)'], assignments=['week1:admin(weekadmin)']) def _browseToAssignment(self, id): self.browseTo('/assignment/{id}/'.format(id=id)) def test_rename(self): self.login('weekadmin') self._browseToAssignment(self.testhelper.sub_period1_week1.id) self.waitForCssSelector('.devilry_subjectadmin_assignmentoverview') self.rename_test_helper(self.testhelper.sub_period1_week1) def test_rename_failure(self): self.login('weekadmin') self._browseToAssignment(self.testhelper.sub_period1_week1.id) self.waitForCssSelector('.devilry_subjectadmin_assignmentoverview') self.rename_test_failure_helper() def test_delete(self): self.testhelper.add(nodes='uni', subjects=['sub'], periods=['period1:begins(-2):admin(p1admin)'], assignments=['willbedeleted']) self.login('p1admin') self._browseToAssignment(self.testhelper.sub_period1_willbedeleted.id) self.waitForCssSelector('.devilry_subjectadmin_assignmentoverview') assignmenturl = self.selenium.current_url self.perform_delete() self.waitFor(self.selenium, lambda s: s.current_url != assignmenturl) # Will time out and fail unless the page is changed after delete self.assertEquals(Assignment.objects.filter(id=self.testhelper.sub_period1_willbedeleted.id).count(), 0) def test_delete_notparentadmin(self): self.testhelper.add(nodes='uni', subjects=['sub'], periods=['period1:begins(-2)'], assignments=['willbedeleted:admin(willbedeletedadm)']) self.login('willbedeletedadm') self._browseToAssignment(self.testhelper.sub_period1_willbedeleted.id) self.waitForCssSelector('.devilry_subjectadmin_assignmentoverview') 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.testhelper.add_to_path('uni;sub.period1.week1.g1:candidate(goodStud1):examiner(exam1).d1') self.testhelper.add_delivery('sub.period1.week1.g1', {'bad.py': ['print ', 'bah']}) self.login('uniadmin') self._browseToAssignment(self.testhelper.sub_period1_week1.id) self.waitForCssSelector('.devilry_subjectadmin_assignmentoverview') self.click_delete_button() self.waitForText('Only superusers can delete non-empty items') # Will time out and fail unless the dialog is shown
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)
class TestGradeEditorWidget(SubjectAdminSeleniumTestCase): def setUp(self): self.testhelper = TestHelper() def _loginToAssignment(self, username, id): self.loginTo(username, '/assignment/{id}/'.format(id=id)) def test_render(self): self.testhelper.add(nodes='uni', subjects=['sub'], periods=['period1'], assignments=['week2:admin(week2admin)']) assignmentid = self.testhelper.sub_period1_week2.id self._loginToAssignment('week2admin', assignmentid) self.waitForCssSelector('.devilry_subjectadmin_assignmentoverview') self.waitForCssSelector('.devilry_subjectadmin_gradeeditorselect_widget') title = self.selenium.find_element_by_css_selector('.devilry_subjectadmin_gradeeditorselect_widget .titlebox h4').text.strip() body = self.selenium.find_element_by_css_selector('.devilry_subjectadmin_gradeeditorselect_widget .markupmoreinfobox').text.strip() self.assertTrue(title.startswith('Grading system')) self.assertTrue(body.startswith('Approved/not approved')) editlink = self.selenium.find_element_by_css_selector('.devilry_subjectadmin_gradeeditorselect_widget a.edit_link') editpath = '/assignment/{id}/@@grade-editor/'.format(id=assignmentid) self.assertEquals(editlink.get_attribute('href').split('#')[1], editpath)
class TestGradeEditorMixin(SetConfigMixin): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['period1'], assignments=['week2:admin(week2admin)']) self.assignment = self.testhelper.sub_period1_week2 def loginAndLoad(self): self.loginTo('week2admin', '/assignment/{id}/@@grade-editor/'.format(id=self.assignment.id)) self.waitForCssSelector('.devilry_subjectadmin_gradeeditoredit') def wait_for_element(self, cssselector): configeditor = self.waitForAndFindElementByCssSelector('.devilry_subjectadmin_gradeeditoredit .devilry_gradeconfigeditor') return self.waitForAndFindElementByCssSelector(cssselector, within=configeditor) def perform_save(self): savebutton = self.selenium.find_element_by_css_selector('.devilry_subjectadmin_gradeeditoredit .devilry_extjsextras_savebutton') savebutton.click() self.waitFor(self.selenium, lambda s: not s.current_url.endswith('@@grade-editor/')) def waitForConfigEditor(self): self.waitForCssSelector('.devilry_subjectadmin_gradeeditoredit .devilry_gradeconfigeditor')
class GroupsGroupedByRelatedStudentAndAssignmentTest(TestCase): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes="uni", subjects=["sub"], periods=["p1:begins(-24):ends(6)"], assignments=['a1:pub(1)', 'a3:pub(4)', 'a2:pub(3)'], assignmentgroups=["stud1:candidate(student1):examiner(examiner1)", "stud2:candidate(student2):examiner(examiner1)", "stud3:candidate(student3):examiner(examiner1)", "stud4:candidate(student4,student3):examiner(examiner1)"], deadlines=['d1:ends(1)']) def _add_good_feedback(self, group): delivery = self.testhelper.add_delivery(group, {"good.py": "print awesome"}) self.testhelper.add_feedback(delivery, {'grade': '100/100', 'points': 100, 'is_passing_grade': True}) def _add_bad_feedback(self, group): delivery = self.testhelper.add_delivery(group, {"bad.py": "print bad"}) self.testhelper.add_feedback(delivery, {'grade': '0/100', 'points': 0, 'is_passing_grade': False}) def test_iter_assignments(self): grouper = GroupsGroupedByRelatedStudentAndAssignment(self.testhelper.sub_p1) shortnames = [assignment.short_name for assignment in grouper.iter_assignments()] self.assertEquals(shortnames, ['a1', 'a2', 'a3']) def test_iter_students_that_is_candidate_but_not_in_related_none(self): grouper = GroupsGroupedByRelatedStudentAndAssignment(self.testhelper.sub_p1) self.assertEqual(len(list(grouper.iter_relatedstudents_with_results())), 0) def test_iter_students_that_is_candidate_but_not_in_related(self): grouper = GroupsGroupedByRelatedStudentAndAssignment(self.testhelper.sub_p1) ignored = list(grouper.iter_students_that_is_candidate_but_not_in_related()) self.assertEquals(len(ignored), 4) student1_info = None for aggregated_relstudentinfo in ignored: if aggregated_relstudentinfo.user == self.testhelper.student1: student1_info = aggregated_relstudentinfo break grouplists = list(student1_info.iter_groups_by_assignment()) self.assertEquals(len(grouplists), 3) # Should match the number of assignments self.assertEquals(len(grouplists[0]), 1) self.assertEquals(grouplists[0][0].feedback, None) def test_iter_students_with_feedback_that_is_candidate_but_not_in_related_none(self): grouper = GroupsGroupedByRelatedStudentAndAssignment(self.testhelper.sub_p1) self.assertEquals(len(list(grouper.iter_students_with_feedback_that_is_candidate_but_not_in_related())), 0) self.assertEquals(len(list(grouper.iter_relatedstudents_with_results())), 0) def test_iter_students_with_feedback_that_is_candidate_but_not_in_related(self): self._add_bad_feedback(self.testhelper.sub_p1_a1_stud1) grouper = GroupsGroupedByRelatedStudentAndAssignment(self.testhelper.sub_p1) ignored = list(grouper.iter_students_with_feedback_that_is_candidate_but_not_in_related()) self.assertEquals(len(ignored), 1) grouplists = list(ignored[0].iter_groups_by_assignment()) self.assertEquals(len(grouplists), 3) # Should match the number of assignments self.assertEquals(grouplists[0][0].feedback.grade, '0/100') def test_iter_relatedstudents_with_results(self): self._add_bad_feedback(self.testhelper.sub_p1_a1_stud1) self.testhelper.sub_p1.relatedstudent_set.create(user=self.testhelper.student1) grouper = GroupsGroupedByRelatedStudentAndAssignment(self.testhelper.sub_p1) results = list(grouper.iter_relatedstudents_with_results()) self.assertEqual(len(results), 1) student1info = results[0] grouplists = list(student1info.iter_groups_by_assignment()) self.assertEqual(len(grouplists), 3) # Should match the number of assignments self.assertEqual(grouplists[0].get_best_gradestring(), '0/100') def test_iter_relatedstudents_with_results_multi(self): self.testhelper.sub_p1.relatedstudent_set.create(user=self.testhelper.student1) self.testhelper.sub_p1.relatedstudent_set.create(user=self.testhelper.student2) grouper = GroupsGroupedByRelatedStudentAndAssignment(self.testhelper.sub_p1) results = list(grouper.iter_relatedstudents_with_results()) self.assertEqual(len(results), 2)
def create_testgroups(period, assignments, **shared_kwargs): logging.info(str(period)) for kwargs in assignments: kw = dict() kw.update(shared_kwargs) kw.update(kwargs) create_example_assignment(period, **kw) def add_extra_relatedusers(period): for username in ('huey', 'dewey', 'louie', 'april', 'may', 'june'): models.RelatedStudent.objects.create(user=User.objects.get(username=username), period=period) testhelper = TestHelper() testhelper.add() testhelper.add(nodes='duckburgh.univ:admin(duckburghboss)', subjects=['duck1100:admin(donald):ln(DUCK1100 - Getting started with python)', 'duck1080:admin(daisy):ln(DUCK1080 - Making the illogical seem logical)', 'duck3580:admin(clarabelle):ln(DUCK3580 - Making the web work)', 'duck5063:admin(scrooge):ln(DUCK5063 - Make low level stuff - avoiding permanent psychological scarring of most of the students)'], periods=['spring01:admin(fethry,gus,gladstone):ln(Spring year zero)']) if args.duckburghusers: add_extra_relatedusers(testhelper.duck1100_spring01) # Duck 1100 create_testgroups(testhelper.duck1100_spring01, num_students = args.num_students, num_examiners = args.num_examiners, deliverycountrange=args.deliverycountrange, assignments = [