class TestRestListOrCreateAssignmentRest(TestCase): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni:admin(uniadmin)', subjects=['duck2000'], periods=['someperiod:begins(-2):ends(6):admin(periodadm)'], assignments=['first:admin(firstadmin)', 'second:admin(secondadmin,firstadmin)', 'third']) self.testhelper.add_to_path('uni;duck9000.otherperiod:begins(-3):ends(6).someassignment:admin(firstadmin)') self.client = RestClient() self.url = '/devilry_subjectadmin/rest/assignment/' self.testhelper.create_user('nobody') def _listas(self, username, **data): self.client.login(username=username, password='******') return self.client.rest_get(self.url, **data) def test_list(self): content, response = self._listas('firstadmin') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 3) self.assertEquals(set(content[0].keys()), set(['id', 'parentnode', 'etag', 'short_name', 'long_name', 'publishing_time', 'delivery_types', 'is_published', 'publishing_time_offset_from_now', 'scale_points_percent', 'first_deadline', 'anonymous', 'deadline_handling'])) def test_list_nonadmin(self): self.testhelper.create_user('otheruser') content, response = self._listas('otheruser') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 0) def test_list_in_subject(self): self.testhelper.add(nodes='uni', subjects=['sub'], periods=['per'], assignments=['a', 'b']) content, response = self._listas('uniadmin', parentnode=self.testhelper.sub_per.id) self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 2) shortnames = set([a['short_name'] for a in content]) self.assertEquals(shortnames, set(['a', 'b'])) def _createas(self, username, data): self.client.login(username=username, password='******') return self.client.rest_post(self.url, data) def test_create(self): content, response = self._createas('periodadm', {'short_name': 'test', 'long_name': 'Test', 'admins': [], 'anonymous': True, 'publishing_time': isoformat_relativetime(days=2), 'first_deadline': isoformat_relativetime(days=3), 'scale_points_percent': 100, 'deadline_handling': 0, 'delivery_types': 0, 'parentnode': self.testhelper.duck2000_someperiod.id}) self.assertEquals(response.status_code, 201) self.assertEquals(content['delivery_types'], 0) self.assertEquals(content['scale_points_percent'], 100) self.assertTrue(content['publishing_time'] != None) self.assertTrue(content['first_deadline'] != None) self.assertEquals(content['long_name'], 'Test') self.assertEquals(content['short_name'], 'test') self.assertEquals(content['anonymous'], True) self.assertEquals(content['parentnode'], self.testhelper.duck2000_someperiod.id) created = Assignment.objects.get(id=content['id']) self.assertEquals(created.short_name, 'test') self.assertEquals(created.long_name, 'Test') self.assertEquals(created.delivery_types, 0) self.assertEquals(created.anonymous, True) self.assertEquals(created.scale_points_percent, 100) self.assertEquals(created.deadline_handling, 0) self.assertEquals(created.parentnode.id, self.testhelper.duck2000_someperiod.id) admins = created.admins.all() self.assertEquals(len(admins), 0) def test_create_nobody(self): content, response = self._createas('nobody', {'short_name': 'test', 'long_name': 'Test', 'admins': [], 'publishing_time': isoformat_relativetime(days=-2), 'scale_points_percent': 100, 'deadline_handling': 0, 'delivery_types': 0, 'parentnode': self.testhelper.duck2000_someperiod.id}) self.assertEquals(response.status_code, 403) self.assertEquals(content['detail'], 'Permission denied') def test_create_admins(self): self.testhelper.create_user('testadmin') content, response = self._createas('uniadmin', {'short_name': 'test', 'long_name': 'Test', 'admins': [{'id': self.testhelper.testadmin.id}], 'publishing_time': isoformat_relativetime(days=-2), 'scale_points_percent': 100, 'deadline_handling': 0, 'delivery_types': 0, 'parentnode': self.testhelper.duck2000.id}) self.assertEquals(response.status_code, 201) created = Assignment.objects.get(id=content['id']) admins = created.admins.all() self.assertEquals(len(admins), 1) self.assertEquals(admins[0].username, 'testadmin')
class TestRestMergeIntoGroup(TestCase): def setUp(self): self.client = RestClient() self.testhelper = TestHelper() self.testhelper.add( nodes="uni", subjects=["sub"], periods=["p1:begins(-2)"], assignments=["a1:admin(a1admin)"] # 2 months ago ) self.assignment = self.testhelper.sub_p1_a1 self.url = "/devilry_subjectadmin/rest/mergeintogroup/{0}".format(self.assignment.id) def _postas(self, username, data): self.client.login(username=username, password="******") return self.client.rest_post(self.url, data) def test_post(self): self.testhelper.add_to_path("uni;sub.p1.a1.g1:candidate(student1,student2):examiner(examiner1).d1") 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}) source = self.testhelper.sub_p1_a1_g1 self.testhelper.add_to_path("uni;sub.p1.a1.g2:candidate(student1,student3):examiner(examiner2)") target = self.testhelper.sub_p1_a1_g2 self.assertEquals(self.assignment.assignmentgroups.count(), 2) content, response = self._postas( "a1admin", {"source_group_ids": [{"id": source.id}], "target_group_id": target.id} ) self.assertEquals(response.status_code, 200) self.assertEquals(content["success"], True) self.assertEquals(content["target_group_id"], target.id) self.assertEquals(content["source_group_ids"], [{"id": source.id}]) self.assertEquals(self.assignment.assignmentgroups.count(), 1) merged_target = self.assignment.assignmentgroups.all()[0] self.assertEquals(merged_target.candidates.count(), 3) self.assertEquals(merged_target.examiners.count(), 2) def test_post_multiple(self): self.testhelper.add_to_path("uni;sub.p1.a1.source1:candidate(student1,student2):examiner(examiner1).d1") self.testhelper.add_to_path("uni;sub.p1.a1.source2:candidate(student1,student2)") self.testhelper.add_to_path("uni;sub.p1.a1.source3:candidate(student1)") self.testhelper.add_to_path("uni;sub.p1.a1.source4:candidate(student6)") source_group_ids = [] for num in xrange(1, 5): group = getattr(self.testhelper, "sub_p1_a1_source{0}".format(num)) source_group_ids.append({"id": group.id}) self.assertEquals(len(source_group_ids), 4) self.testhelper.add_to_path("uni;sub.p1.a1.g2:candidate(student1,student3):examiner(examiner2)") target = self.testhelper.sub_p1_a1_g2 self.assertEquals(self.assignment.assignmentgroups.count(), 5) content, response = self._postas( "a1admin", {"source_group_ids": source_group_ids, "target_group_id": target.id} ) self.assertEquals(response.status_code, 200) self.assertEquals(content["success"], True) self.assertEquals(content["target_group_id"], target.id) self.assertEquals(content["source_group_ids"], source_group_ids) self.assertEquals(self.assignment.assignmentgroups.count(), 1) merged_target = self.assignment.assignmentgroups.all()[0] self.assertEquals(merged_target.candidates.count(), 4) self.assertEquals(merged_target.examiners.count(), 2) def test_post_nobody(self): self.testhelper.create_user("nobody") content, response = self._postas("nobody", {"source_group_ids": [{"id": 1}], "target_group_id": 1}) self.assertEquals(response.status_code, 403) def test_post_not_found(self): content, response = self._postas( "a1admin", {"source_group_ids": [{"id": 10000000}], "target_group_id": 1100000} ) self.assertEquals(response.status_code, 404)
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 TestRestCreateNewAssignmentIntegration(TestCase): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['p1:admin(p1admin)', 'p2']) self.client = RestClient() self.url = '/devilry_subjectadmin/rest/createnewassignment/' def _login_p1admin(self): self.client.login(username='******', password='******') def _get_testdata(self): publishing_time = self.testhelper.sub_p1.start_time + timedelta(days=1) first_deadline = self.testhelper.sub_p1.start_time + timedelta(days=2) return dict(period_id=self.testhelper.sub_p1.id, short_name='a', long_name='Aa', first_deadline=isoformat_datetime(first_deadline), publishing_time=isoformat_datetime(publishing_time), delivery_types=ELECTRONIC, anonymous=False, setupstudents_mode='do_not_setup', setupexaminers_mode='do_not_setup') def test_create(self): self._login_p1admin() publishing_time = self.testhelper.sub_p1.start_time + timedelta(days=1) first_deadline = self.testhelper.sub_p1.start_time + timedelta(days=2) content, response = self.client.rest_post(self.url, self._get_testdata()) self.assertEquals(response.status_code, 201) self.assertEquals(set(content.keys()), set(['id', 'period_id', 'short_name', 'long_name', 'first_deadline', 'anonymous'])) def test_create_notfound(self): self._login_p1admin() data = self._get_testdata() data['period_id'] = 200000 content, response = self.client.rest_post(self.url, data) self.assertEquals(response.status_code, 403) def test_create_permissiondenied(self): self.testhelper.create_user('nopermsuser') self.client.login(username='******', password='******') data = self._get_testdata() content, response = self.client.rest_post(self.url, data) self.assertEquals(response.status_code, 403) def test_create_validation(self): self._login_p1admin() content, response = self.client.rest_post(self.url, {}) self.assertEquals(response.status_code, 400) self.assertEquals(content.keys(), ['field_errors']) for fieldname in ['delivery_types', 'long_name', 'publishing_time', 'short_name']: self.assertEquals(content['field_errors'][fieldname], [u'This field is required.']) def test_create_first_deadline_none(self): self._login_p1admin() data = self._get_testdata() data['first_deadline'] = None data['setupstudents_mode'] = 'allrelated' content, response = self.client.rest_post(self.url, data) self.assertEquals(response.status_code, 400) self.assertTrue(content['field_errors']['first_deadline'][0].startswith('Required when adding'))
class TestRestDeadlinesBulkCreate(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): return '/devilry_subjectadmin/rest/deadlinesbulk/{0}/'.format(self.testhelper.sub_p1_a1.id) def _postas(self, username, data): self.client.login(username=username, password='******') return self.client.rest_post(self._geturl(), data) def _itergroups(self): for groupnum in xrange(3): group_id = getattr(self.testhelper, 'sub_p1_a1_g{0}'.format(groupnum)).id group = AssignmentGroup.objects.get(id=group_id) yield group def test_post_no_matching_groups(self): for group in self._itergroups(): deadlines = group.deadlines.all().order_by('-deadline') self.assertEquals(group.feedback, None) new_deadline = datetime(2004, 12, 24, 20, 30) content, response = self._postas('adm', {'deadline': format_datetime(new_deadline), 'text': 'Created', 'createmode': 'failed'}) self.assertEquals(response.status_code, 400) self.assertEquals(content['field_errors']['createmode'], ['The given option did not match any groups.']) def test_post_createmode_failed(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}) g1 = AssignmentGroup.objects.get(id=self.testhelper.sub_p1_a1_g1.id) self.assertFalse(g1.is_open) new_deadline = datetime(2004, 12, 24, 20, 30) self.assertEquals(Deadline.objects.filter(deadline=new_deadline).count(), 0) content, response = self._postas('adm', {'deadline': format_datetime(new_deadline), 'text': 'Created', 'createmode': 'failed'}) # Check response self.assertEquals(response.status_code, 201) self.assertEquals(decode_bulkdeadline_id(content['bulkdeadline_id'])[0], new_deadline) self.assertEquals(len(content['groups']), 1) self.assertEquals(content['text'], 'Created') self.assertEquals(content['deadline'], format_datetime(new_deadline)) # Check actual data self.assertEquals(Deadline.objects.filter(deadline=new_deadline).count(), 1) g1 = AssignmentGroup.objects.get(id=self.testhelper.sub_p1_a1_g1.id) deadlines = g1.deadlines.all().order_by('-deadline') self.assertEquals(len(deadlines), 2) self.assertEquals(deadlines[0].deadline, new_deadline) self.assertEquals(deadlines[0].text, 'Created') self.assertTrue(g1.is_open) # Group was automatically opened in devilry.apps.core.models.Deadline.save() def test_post_createmode_failed_or_no_feedback(self): # Fail g0 self.testhelper.add_delivery('sub.p1.a1.g0', {'bad.py': ['print ', 'bah']}) self.testhelper.add_feedback('sub.p1.a1.g0', verdict={'grade': 'F', 'points': 30, 'is_passing_grade': False}) # Pass g1 self.testhelper.add_delivery('sub.p1.a1.g1', {'good.py': ['print ', 'bah']}) self.testhelper.add_feedback('sub.p1.a1.g1', verdict={'grade': 'A', 'points': 100, 'is_passing_grade': True}) # g2 has no feedback self.assertEquals(self.testhelper.sub_p1_a1_g2.feedback, None) new_deadline = datetime(2004, 12, 24, 20, 30) self.assertEquals(Deadline.objects.filter(deadline=new_deadline).count(), 0) content, response = self._postas('adm', {'deadline': format_datetime(new_deadline), 'text': 'Created', 'createmode': 'failed-or-no-feedback'}) # Check response self.assertEquals(response.status_code, 201) self.assertEquals(len(content['groups']), 2) # Check actual data self.assertEquals(Deadline.objects.filter(deadline=new_deadline).count(), 2) g0 = self.testhelper.sub_p1_a1_g0 g2 = self.testhelper.sub_p1_a1_g2 for group in (g0, g2): deadlines = group.deadlines.all().order_by('-deadline') self.assertEquals(len(deadlines), 2) self.assertEquals(deadlines[0].deadline, new_deadline) self.assertEquals(deadlines[0].text, 'Created') g1 = self.testhelper.sub_p1_a1_g1 self.assertEquals(g1.deadlines.count(), 1) # We did not a deadline to g1 because they have passing grade def test_post_createmode_no_deadlines(self): self.assertEquals(self.testhelper.sub_p1_a1_g1.deadlines.count(), 1) self.testhelper.add_to_path('uni;sub.p1.a1.extragroup') self.assertEquals(self.testhelper.sub_p1_a1_extragroup.deadlines.count(), 0) new_deadline = datetime(2004, 12, 24, 20, 30) self.assertEquals(Deadline.objects.filter(deadline=new_deadline).count(), 0) content, response = self._postas('adm', {'deadline': format_datetime(new_deadline), 'text': 'Created', 'createmode': 'no-deadlines'}) # Check response self.assertEquals(response.status_code, 201) self.assertEquals(decode_bulkdeadline_id(content['bulkdeadline_id'])[0], new_deadline) self.assertEquals(len(content['groups']), 1) self.assertEquals(content['text'], 'Created') self.assertEquals(content['deadline'], format_datetime(new_deadline)) # Check actual data self.assertEquals(Deadline.objects.filter(deadline=new_deadline).count(), 1) extragroup = AssignmentGroup.objects.get(id=self.testhelper.sub_p1_a1_extragroup.id) deadlines = extragroup.deadlines.all() self.assertEquals(len(deadlines), 1) self.assertEquals(deadlines[0].deadline, new_deadline) self.assertEquals(deadlines[0].text, 'Created') self.assertTrue(extragroup.is_open) # Group was automatically opened in devilry.apps.core.models.Deadline.save() def test_post_createmode_specific_groups(self): self.assertEquals(self.testhelper.sub_p1_a1_g1.deadlines.count(), 1) self.assertEquals(self.testhelper.sub_p1_a1_g2.deadlines.count(), 1) new_deadline = datetime(2004, 12, 24, 20, 30) self.assertEquals(Deadline.objects.filter(deadline=new_deadline).count(), 0) content, response = self._postas('adm', {'deadline': format_datetime(new_deadline), 'text': 'Created', 'group_ids': [self.testhelper.sub_p1_a1_g1.id, self.testhelper.sub_p1_a1_g2.id], 'createmode': 'specific-groups'}) # Check response self.assertEquals(response.status_code, 201) self.assertEquals(decode_bulkdeadline_id(content['bulkdeadline_id'])[0], new_deadline) self.assertEquals(len(content['groups']), 2) self.assertEquals(content['text'], 'Created') self.assertEquals(content['deadline'], format_datetime(new_deadline)) # Check actual data self.assertEquals(Deadline.objects.filter(deadline=new_deadline).count(), 2) g1 = self.testhelper.reload_from_db(self.testhelper.sub_p1_a1_g1) deadlines = g1.deadlines.all() self.assertEquals(len(deadlines), 2) self.assertEquals(deadlines[0].deadline, new_deadline) self.assertEquals(deadlines[0].text, 'Created') def test_post_createmode_specific_groups_nogroups(self): new_deadline = datetime(2004, 12, 24, 20, 30) self.assertEquals(Deadline.objects.filter(deadline=new_deadline).count(), 0) content, response = self._postas('adm', {'deadline': format_datetime(new_deadline), 'text': 'Created', 'createmode': 'specific-groups'}) self.assertEquals(response.status_code, 400) self.assertEquals(content['field_errors']['group_ids'][0], '``group_ids`` is required when ``createmode=="specific-groups"``.') def test_post_nobody(self): self.testhelper.create_user('nobody') content, response = self._postas('nobody', {}) self.assertEquals(response.status_code, 403)
class TestRestListOrCreatePeriodRest(TestCase): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni:admin(uniadmin)', subjects=['duck2000:admin(subadmin)'], periods=['one:admin(adminone)', 'two', 'three:admin(adminone)']) self.client = RestClient() self.url = '/devilry_subjectadmin/rest/period/' self.testhelper.create_user('nobody') def _listas(self, username, **data): self.client.login(username=username, password='******') return self.client.rest_get(self.url, **data) def test_list(self): content, response = self._listas('adminone') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 2) self.assertEquals(set(content[0].keys()), set(['id', 'parentnode', 'etag', 'short_name', 'long_name', 'start_time', 'end_time', 'url'])) def test_list_nonadmin(self): self.testhelper.create_user('otheruser') content, response = self._listas('otheruser') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 0) def test_list_in_subject(self): self.testhelper.add(nodes='uni:admin(uniadmin)', subjects=['duck9000'], periods=['p1', 'p2']) content, response = self._listas('uniadmin', parentnode=self.testhelper.duck9000.id) self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 2) shortnames = set([p['short_name'] for p in content]) self.assertEquals(shortnames, set(['p1', 'p2'])) def _createas(self, username, data): self.client.login(username=username, password='******') return self.client.rest_post(self.url, data) def test_create(self): content, response = self._createas('subadmin', {'short_name': 'test', 'long_name': 'Test', 'admins': [], 'start_time': isoformat_relativetime(days=-2), 'end_time': isoformat_relativetime(days=2), 'parentnode': self.testhelper.duck2000.id}) self.assertEquals(response.status_code, 201) self.assertEquals(content['long_name'], 'Test') self.assertEquals(content['short_name'], 'test') self.assertEquals(content['parentnode'], self.testhelper.duck2000.id) created = Period.objects.get(id=content['id']) self.assertEquals(created.short_name, 'test') self.assertEquals(created.long_name, 'Test') self.assertEquals(created.parentnode.id, self.testhelper.duck2000.id) admins = created.admins.all() self.assertEquals(len(admins), 0) def test_create_nobody(self): content, response = self._createas('nobody', {'short_name': 'test', 'long_name': 'Test', 'admins': [], 'start_time': isoformat_relativetime(days=-2), 'end_time': isoformat_relativetime(days=2), 'parentnode': self.testhelper.duck2000.id}) self.assertEquals(response.status_code, 403) self.assertEquals(content['detail'], 'Permission denied') def test_create_admins(self): self.testhelper.create_user('testadmin') content, response = self._createas('uniadmin', {'short_name': 'test', 'long_name': 'Test', 'admins': [{'id': self.testhelper.testadmin.id}], 'start_time': isoformat_relativetime(days=-2), 'end_time': isoformat_relativetime(days=2), 'parentnode': self.testhelper.duck2000.id}) self.assertEquals(response.status_code, 201) created = Period.objects.get(id=content['id']) admins = created.admins.all() self.assertEquals(len(admins), 1) self.assertEquals(admins[0].username, 'testadmin')
class TestListOrCreateRelatedUserMixin(object): def setUp(self): self.client = RestClient() self.testhelper = TestHelper() self.testhelper.add(nodes="uni", subjects=["sub"], periods=["p1:admin(p1admin)", "p2:admin(p2admin)"]) self.testhelper.create_superuser("superuser") self.testhelper.create_user("testuser") def get_url(self): """ Get url of rest API. """ raise NotImplementedError() def _listas(self, username, **data): self.client.login(username=username, password="******") return self.client.rest_get(self.get_url(), **data) def _create_user(self, index): username = "******".format(index) user = self.testhelper.create_user(username) user.email = username + "@example.com" user.devilryuserprofile.full_name = "User {0}".format(index) user.save() user.devilryuserprofile.save() return user def create_relateduser(self, period, index, tags=""): """ Create a related user of the type that we are testing. """ raise NotImplementedError() def _create_relatedusers(self, count): for index in xrange(count): self.create_relateduser(self.testhelper.sub_p1, index) def test_list(self): self._create_relatedusers(2) self.create_relateduser(self.testhelper.sub_p1, index=5, tags="group1,group2") self.create_relateduser( self.testhelper.sub_p2, index=20, tags="" ) # Not on p1, so we shold not get this in the listing! content, response = self._listas("p1admin") self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 3) # Since this is 3, we did not get the user registered on p2. first, second, last = content self.assertEquals(first["user"]["username"], "reluser0") self.assertEquals(first["user"]["full_name"], "User 0") self.assertEquals(first["tags"], "") self.assertEquals(second["tags"], "") self.assertEquals(second["user"]["username"], "reluser1") self.assertEquals(last["user"]["username"], "reluser5") self.assertEquals(last["tags"], "group1,group2") return content def test_list_none(self): content, response = self._listas("p1admin") self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 0) def test_list_superuser(self): self._create_relatedusers(2) content, response = self._listas("superuser") self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 2) def test_list_not_admin(self): self._create_relatedusers(2) content, response = self._listas("p2admin") self.assertEquals(response.status_code, 403) def _listqueryas(self, username, query): self.client.login(username=username, password="******") return self.client.rest_get(self.get_url(), **{"query": query}) def test_list_query(self): self._create_relatedusers(2) self.create_relateduser(self.testhelper.sub_p1, index=5, tags="group1,group2") self.create_relateduser( self.testhelper.sub_p2, index=20, tags="" ) # Not on p1, so we shold not get this in the listing! self.testhelper.reluser0.devilryuserprofile.full_name = "Superhero" self.testhelper.reluser0.devilryuserprofile.save() self.testhelper.reluser1.devilryuserprofile.full_name = "Super Not hero" self.testhelper.reluser1.email = "*****@*****.**" self.testhelper.reluser1.devilryuserprofile.save() self.testhelper.reluser1.save() content, response = self._listqueryas("p1admin", query="5") self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 1) content, response = self._listqueryas("p1admin", query="HeRo") self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 2) content, response = self._listqueryas("p1admin", query="group2") self.assertEquals(len(content), 1) content, response = self._listqueryas("p1admin", query="nothero@exAM") self.assertEquals(len(content), 1) def _createas(self, username, data): self.client.login(username=username, password="******") return self.client.rest_post(self.get_url(), data) def get_valid_createdata(self): """ Overridden in TestListOrCreateRelatedStudentRest. """ return { "period": self.testhelper.sub_p1.id, "user": self.testhelper.testuser.id, # TODO: Support username "tags": "tag1,tag2", } def _create_test_helper(self, username): self.assertEquals(self.modelcls.objects.all().count(), 0) content, response = self._createas(username, self.get_valid_createdata()) self.assertEquals(response.status_code, 201) self.assertEquals(content["user"].keys(), [u"username", u"email", u"full_name", u"id"]) self.assertEquals(content["user"]["username"], "testuser") self.assertEquals(content["user"]["id"], self.testhelper.testuser.id) self.assertEquals(content["tags"], "tag1,tag2") self.assertEquals(content["period"], self.testhelper.sub_p1.id) self.assertEquals(self.modelcls.objects.all().count(), 1) created = self.modelcls.objects.all()[0] self.assertEquals(created.user.username, "testuser") return content, created def test_create(self): return self._create_test_helper("p1admin") def test_create_not_admin(self): content, response = self._createas("p2admin", self.get_valid_createdata()) self.assertEquals(response.status_code, 403) def test_create_superuser(self): content, response = self._create_test_helper("superuser")
class TestRestPopFromGroup(TestCase): def setUp(self): self.client = RestClient() self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['p1:begins(-2)'], # 2 months ago assignments=['a1:admin(a1admin)']) self.assignment = self.testhelper.sub_p1_a1 self.url = '/devilry_subjectadmin/rest/popfromgroup/{0}'.format(self.assignment.id) def _postas(self, username, data): self.client.login(username=username, password='******') return self.client.rest_post(self.url, data) def test_post(self): self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate(student1,student2):examiner(examiner1).d1') 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}) source = self.testhelper.sub_p1_a1_g1 student1cand = source.candidates.get(student=self.testhelper.student1) self.assertEquals(self.assignment.assignmentgroups.count(), 1) content, response = self._postas('a1admin', {'group_id': source.id, 'candidate_id': student1cand.id}) self.assertEquals(response.status_code, 200) self.assertEquals(self.assignment.assignmentgroups.count(), 2) self.assertEquals(content['success'], True) self.assertEquals(content['group_id'], source.id) self.assertNotEquals(content['new_group_id'], source.id) self.assertEquals(source.candidates.count(), 1) self.assertEquals(source.candidates.all()[0].student.username, 'student2') newgroup = self.assignment.assignmentgroups.get(~Q(id=source.id)) self.assertEquals(content['new_group_id'], newgroup.id) self.assertEquals(newgroup.candidates.count(), 1) self.assertEquals(newgroup.candidates.all()[0].student.username, 'student1') # Some sanity tests. Note that all of this is already tested in the tests for AssignmentGroup.pop_candidate def get_delivery(group): return Delivery.objects.get(deadline__assignment_group=group) delivery = get_delivery(source) newdelivery = get_delivery(newgroup) self.assertEquals(delivery.time_of_delivery, newdelivery.time_of_delivery) self.assertEquals(delivery.feedbacks.all()[0].grade, newdelivery.feedbacks.all()[0].grade) self.assertEquals(newdelivery.feedbacks.all()[0].grade, 'F') def test_post_nobody(self): self.testhelper.create_user('nobody') content, response = self._postas('nobody', {'group_id': 1, 'candidate_id': 1}) self.assertEquals(response.status_code, 403) def test_post_to_few_candidates(self): self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate(student1):examiner(examiner1).d1') source = self.testhelper.sub_p1_a1_g1 student1cand = source.candidates.get(student=self.testhelper.student1) content, response = self._postas('a1admin', {'group_id': source.id, 'candidate_id': student1cand.id}) self.assertEquals(response.status_code, 400) self.assertEquals(content['detail'], 'Can not pop candidates on a group with less than 2 candidates.') def test_post_not_candidate_on_group(self): self.testhelper.add_to_path('uni;sub.p1.a1.g1:candidate(student1, student2)') self.testhelper.add_to_path('uni;sub.p1.a1.g2:candidate(notcandong1)') source = self.testhelper.sub_p1_a1_g1 notcandong1Cand = self.testhelper.sub_p1_a1_g2.candidates.get(student=self.testhelper.notcandong1) content, response = self._postas('a1admin', {'group_id': source.id, 'candidate_id': notcandong1Cand.id}) self.assertEquals(response.status_code, 404)
class TestGroupRest(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(len(content), 1) first = content[0] self.assertEquals(set(first.keys()), set(['name', 'id', 'etag', 'status', 'is_open', 'parentnode', 'feedback', 'deadlines', 'candidates', 'tags', 'examiners', 'num_deliveries'])) self.assertEquals(first['name'], 'g1') self.assertEquals(first['is_open'], False) self.assertEquals(first['parentnode'], self.a1id) self.assertEquals(first['num_deliveries'], 0) self.assertEquals(first['feedback'], None) self.assertEquals(first['deadlines'], []) self.assertEquals(first['candidates'], []) self.assertEquals(first['examiners'], []) self.assertEquals(first['tags'], []) groups = self.testhelper.sub_p1_a1.assignmentgroups.all() self.assertEquals(len(groups), 1) self.assertEquals(first['id'], groups[0].id) def _test_create_as(self, username): a1 = self.testhelper.sub_p1_a1 a1.first_deadline = datetime(2005, 1, 1) a1.save() 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(len(content), 1) first = content[0] self.assertEquals(first['name'], 'g1') self.assertEquals(first['is_open'], True) # NOTE: Overrides the parameter since first_deadline is set. self.assertEquals(first['parentnode'], self.a1id) self.assertEquals(first['num_deliveries'], 0) # Feedback self.assertEquals(first['feedback'], None) # Deadlines self.assertEquals(len(first['deadlines']), 1) self.assertEquals(first['deadlines'][0]['deadline'], '2005-01-01T00:00:00') self.assertEquals(set(first['deadlines'][0].keys()), set(['id', 'deadline'])) # Tags self.assertEquals(len(first['tags']), 1) tag = first['tags'][0] self.assertEquals(tag['tag'], 'mytag') self.assertEquals(set(tag.keys()), set(['id', 'tag'])) # Examiners self.assertEquals(len(first['examiners']), 1) examiner = first['examiners'][0] self.assertEquals(set(examiner.keys()), set(['id', 'user'])) self.assertEquals(set(examiner['user'].keys()), set(['email', 'full_name', 'id', 'username', 'displayname'])) self.assertEquals(examiner['user']['id'], self.testhelper.examiner1.id) self.assertEquals(examiner['user']['username'], 'examiner1') # Candidates self.assertEquals(len(first['candidates']), 1) candidate = first['candidates'][0] self.assertEquals(set(candidate.keys()), set(['id', 'user', 'candidate_id'])) self.assertEquals(set(candidate['user'].keys()), set(['email', 'full_name', 'id', 'username', 'displayname'])) 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(first['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': None, '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) # # # PUT # # def _putas(self, username, assignment_id, data={}): self.client.login(username=username, password='******') return self.client.rest_put(self._geturl(assignment_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 = [{'id': group.id, 'name': 'changed', 'is_open': False}] content, response = self._putas('a1admin', self.a1id, data) self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 1) first = content[0] self.assertEquals(set(first.keys()), set(['name', 'id', 'etag', 'status', 'is_open', 'parentnode', 'feedback', 'deadlines', 'candidates', 'tags', 'examiners', 'num_deliveries'])) self.assertEquals(first['name'], 'changed') self.assertEquals(first['is_open'], False) self.assertEquals(first['parentnode'], self.a1id) self.assertEquals(first['num_deliveries'], 0) self.assertEquals(first['feedback'], None) self.assertEquals(first['deadlines'], []) self.assertEquals(first['candidates'], []) self.assertEquals(first['examiners'], []) self.assertEquals(first['tags'], []) groups = self.testhelper.sub_p1_a1.assignmentgroups.all() self.assertEquals(len(groups), 1) self.assertEquals(first['id'], groups[0].id) def _test_put_as(self, username): group = self._add_group('g1', candidates='candidate2', examiners='examiner2') data = [{'id': group.id, '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, data) #from pprint import pprint #print 'Response content:' #pprint(content) self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 1) first = content[0] self.assertEquals(first['name'], 'changed') self.assertEquals(first['is_open'], False) self.assertEquals(first['parentnode'], self.a1id) self.assertEquals(first['num_deliveries'], 0) # Feedback self.assertEquals(first['feedback'], None) # Deadlines self.assertEquals(first['deadlines'], []) # Tags self.assertEquals(len(first['tags']), 1) tag = first['tags'][0] self.assertEquals(tag['tag'], 'mytag') self.assertEquals(set(tag.keys()), set(['id', 'tag'])) # Examiners self.assertEquals(len(first['examiners']), 1) examiner = first['examiners'][0] self.assertEquals(set(examiner.keys()), set(['id', 'user'])) self.assertEquals(set(examiner['user'].keys()), set(['email', 'full_name', 'id', 'username', 'displayname'])) self.assertEquals(examiner['user']['id'], self.testhelper.examiner1.id) self.assertEquals(examiner['user']['username'], 'examiner1') # Candidates self.assertEquals(len(first['candidates']), 1) candidate = first['candidates'][0] self.assertEquals(set(candidate.keys()), set(['id', 'user', 'candidate_id'])) self.assertEquals(set(candidate['user'].keys()), set(['email', 'full_name', 'id', 'username', 'displayname'])) 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.testhelper.create_superuser('superuser') self._test_put_as('superuser') def test_put_as_assignmentadmin(self): self._test_put_as('a1admin') def test_put_doesnotexist(self): data = [{'id': 100000, 'name': 'changed', 'is_open': False}] content, response = self._putas('grandma', 10000, 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, 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 = [{'id': group.id, 'name': 'changed', 'is_open': False, 'feedback': 'should be ignored', 'num_deliveries': 'should be ignored', 'deadlines': 'should be ignored'}] content, response = self._putas('a1admin', self.a1id, data) self.assertEquals(response.status_code, 200) # # # DELETE # # def _add_group_with_delivery(self, name, **kwargs): group = self._add_group(name, **kwargs) self.testhelper.add_to_path('uni;sub.p1.a1.{0}.d1'.format(name)) self.testhelper.add_delivery(group) return group def _deleteas(self, username, assignment_id, data): self.client.login(username=username, password='******') return self.client.rest_put(self._geturl(assignment_id), data, X_DEVILRY_DELETEHACK='1') def _test_delete_ok_as(self, group, username): data = [{'id': group.id}] content, response = self._deleteas(username, self.a1id, data) self.assertEquals(response.status_code, 204) self.assertEquals(content, None) self.assertFalse(AssignmentGroup.objects.filter(id=group.id).exists()) def test_delete_as_superuser(self): self.testhelper.create_superuser('superuser') group = self._add_group('g1', candidates='candidate2', examiners='examiner2') self._test_delete_ok_as(group, 'superuser') def test_delete_as_a1admin(self): group = self._add_group('g1', candidates='candidate2', examiners='examiner2') self._test_delete_ok_as(group, 'a1admin') def _test_delete_noperm_as(self, group, username): data = [{'id': group.id}] content, response = self._deleteas(username, self.a1id, data) #from pprint import pprint #print 'Response content:' #pprint(content) self.assertEquals(response.status_code, 403) self.assertTrue(AssignmentGroup.objects.filter(id=group.id).exists()) def test_delete_with_content_as_superuser(self): self.testhelper.create_superuser('superuser') group = self._add_group_with_delivery('g1', candidates='candidate2', examiners='examiner2') self._test_delete_ok_as(group, 'superuser') def test_delete_with_content_as_a1admin(self): group = self._add_group_with_delivery('g1', candidates='candidate2', examiners='examiner2') self._test_delete_noperm_as(group, 'a1admin')
class TestListOrCreateRelatedUserMixin(object): def setUp(self): self.client = RestClient() self.testhelper = TestHelper() self.testhelper.add(nodes='uni', subjects=['sub'], periods=['p1:admin(p1admin)', 'p2:admin(p2admin)']) self.testhelper.create_superuser("superuser") self.testhelper.create_user('testuser') def get_url(self): """ Get url of rest API. """ raise NotImplementedError() def _listas(self, username, **data): self.client.login(username=username, password='******') return self.client.rest_get(self.get_url(), **data) def _create_user(self, index): username = "******".format(index) user = self.testhelper.create_user(username) user.email = username + '@example.com' user.devilryuserprofile.full_name = 'User {0}'.format(index) user.save() user.devilryuserprofile.save() return user def create_relateduser(self, period, index, tags=''): """ Create a related user of the type that we are testing. """ raise NotImplementedError() def _create_relatedusers(self, count): for index in xrange(count): self.create_relateduser(self.testhelper.sub_p1, index) def test_list(self): self._create_relatedusers(2) self.create_relateduser(self.testhelper.sub_p1, index=5, tags='group1,group2') self.create_relateduser(self.testhelper.sub_p2, index=20, tags='') # Not on p1, so we shold not get this in the listing! content, response = self._listas('p1admin') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 3) # Since this is 3, we did not get the user registered on p2. first, second, last = content self.assertEquals(first['user']['username'], 'reluser0') self.assertEquals(first['user']['full_name'] , 'User 0') self.assertEquals(first['tags'], '') self.assertEquals(second['tags'], '') self.assertEquals(second['user']['username'], 'reluser1') self.assertEquals(last['user']['username'], 'reluser5') self.assertEquals(last['tags'], 'group1,group2') return content def test_list_none(self): content, response = self._listas('p1admin') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 0) def test_list_superuser(self): self._create_relatedusers(2) content, response = self._listas('superuser') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 2) def test_list_not_admin(self): self._create_relatedusers(2) content, response = self._listas('p2admin') self.assertEquals(response.status_code, 403) def _listqueryas(self, username, query): self.client.login(username=username, password='******') return self.client.rest_get(self.get_url(), **{'query': query}) def test_list_query(self): self._create_relatedusers(2) self.create_relateduser(self.testhelper.sub_p1, index=5, tags='group1,group2') self.create_relateduser(self.testhelper.sub_p2, index=20, tags='') # Not on p1, so we shold not get this in the listing! self.testhelper.reluser0.devilryuserprofile.full_name = 'Superhero' self.testhelper.reluser0.devilryuserprofile.save() self.testhelper.reluser1.devilryuserprofile.full_name = 'Super Not hero' self.testhelper.reluser1.email = '*****@*****.**' self.testhelper.reluser1.devilryuserprofile.save() self.testhelper.reluser1.save() content, response = self._listqueryas('p1admin', query='5') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 1) content, response = self._listqueryas('p1admin', query='HeRo') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 2) content, response = self._listqueryas('p1admin', query='group2') self.assertEquals(len(content), 1) content, response = self._listqueryas('p1admin', query='nothero@exAM') self.assertEquals(len(content), 1) def _createas(self, username, data): self.client.login(username=username, password='******') return self.client.rest_post(self.get_url(), data) def get_valid_createdata(self): """ Overridden in TestListOrCreateRelatedStudentRest. """ return {'period': self.testhelper.sub_p1.id, 'user': self.testhelper.testuser.id, # TODO: Support username 'tags': 'tag1,tag2'} def _create_test_helper(self, username): self.assertEquals(self.modelcls.objects.all().count(), 0) content, response = self._createas(username, self.get_valid_createdata()) self.assertEquals(response.status_code, 201) self.assertEquals(set(content['user'].keys()), set(['username', 'email', 'full_name', 'id', 'displayname'])) self.assertEquals(content['user']['username'], 'testuser') self.assertEquals(content['user']['id'], self.testhelper.testuser.id) self.assertEquals(content['tags'], 'tag1,tag2') self.assertEquals(content['period'], self.testhelper.sub_p1.id) self.assertEquals(self.modelcls.objects.all().count(), 1) created = self.modelcls.objects.all()[0] self.assertEquals(created.user.username, 'testuser') return content, created def test_create(self): return self._create_test_helper('p1admin') def test_create_not_admin(self): content, response = self._createas('p2admin', self.get_valid_createdata()) self.assertEquals(response.status_code, 403) def test_create_superuser(self): content, response = self._create_test_helper('superuser')
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): self.client.login(username=username, password='******') return self.client.rest_get(self._get_url()) 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): relatedStudent1 = self._create_relatedstudent('student1', 'Student One') relatedStudent2 = self._create_relatedstudent('student2', 'Student Two') self._createlistteststatus(self.testhelper.sub_oldperiod) self._createlistteststatus(self.testhelper.sub_p1, status='notready', plugin='') import time time.sleep(0.1) status = self._createlistteststatus(self.testhelper.sub_p1) status.students.create(relatedstudent=relatedStudent1, qualifies=True) status.students.create(relatedstudent=relatedStudent2, qualifies=False) 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_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
class TestRestListOrCreateAssignmentRest(TestCase): def setUp(self): self.testhelper = TestHelper() self.testhelper.add( nodes="uni:admin(uniadmin)", subjects=["duck2000"], periods=["someperiod:begins(-2):ends(6):admin(periodadm)"], assignments=["first:admin(firstadmin)", "second:admin(secondadmin,firstadmin)", "third"], ) self.testhelper.add_to_path("uni;duck9000.otherperiod:begins(-3):ends(6).someassignment:admin(firstadmin)") self.client = RestClient() self.url = "/devilry_subjectadmin/rest/assignment/" self.testhelper.create_user("nobody") def _listas(self, username, **data): self.client.login(username=username, password="******") return self.client.rest_get(self.url, **data) def test_list(self): content, response = self._listas("firstadmin") self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 3) self.assertEquals( set(content[0].keys()), set( [ "id", "parentnode", "etag", "short_name", "long_name", "publishing_time", "delivery_types", "is_published", "publishing_time_offset_from_now", "scale_points_percent", "first_deadline", "anonymous", "deadline_handling", ] ), ) def test_list_nonadmin(self): self.testhelper.create_user("otheruser") content, response = self._listas("otheruser") self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 0) def test_list_in_subject(self): self.testhelper.add(nodes="uni", subjects=["sub"], periods=["per"], assignments=["a", "b"]) content, response = self._listas("uniadmin", parentnode=self.testhelper.sub_per.id) self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 2) shortnames = set([a["short_name"] for a in content]) self.assertEquals(shortnames, set(["a", "b"])) def _createas(self, username, data): self.client.login(username=username, password="******") return self.client.rest_post(self.url, data) def test_create(self): content, response = self._createas( "periodadm", { "short_name": "test", "long_name": "Test", "admins": [], "anonymous": True, "publishing_time": isoformat_relativetime(days=2), "first_deadline": isoformat_relativetime(days=3), "scale_points_percent": 100, "deadline_handling": 0, "delivery_types": 0, "parentnode": self.testhelper.duck2000_someperiod.id, }, ) self.assertEquals(response.status_code, 201) self.assertEquals(content["delivery_types"], 0) self.assertEquals(content["scale_points_percent"], 100) self.assertTrue(content["publishing_time"] != None) self.assertTrue(content["first_deadline"] != None) self.assertEquals(content["long_name"], "Test") self.assertEquals(content["short_name"], "test") self.assertEquals(content["anonymous"], True) self.assertEquals(content["parentnode"], self.testhelper.duck2000_someperiod.id) created = Assignment.objects.get(id=content["id"]) self.assertEquals(created.short_name, "test") self.assertEquals(created.long_name, "Test") self.assertEquals(created.delivery_types, 0) self.assertEquals(created.anonymous, True) self.assertEquals(created.scale_points_percent, 100) self.assertEquals(created.deadline_handling, 0) self.assertEquals(created.parentnode.id, self.testhelper.duck2000_someperiod.id) admins = created.admins.all() self.assertEquals(len(admins), 0) def test_create_nobody(self): content, response = self._createas( "nobody", { "short_name": "test", "long_name": "Test", "admins": [], "publishing_time": isoformat_relativetime(days=-2), "scale_points_percent": 100, "deadline_handling": 0, "delivery_types": 0, "parentnode": self.testhelper.duck2000_someperiod.id, }, ) self.assertEquals(response.status_code, 403) self.assertEquals(content["detail"], "Permission denied") def test_create_admins(self): self.testhelper.create_user("testadmin") content, response = self._createas( "uniadmin", { "short_name": "test", "long_name": "Test", "admins": [{"id": self.testhelper.testadmin.id}], "publishing_time": isoformat_relativetime(days=-2), "scale_points_percent": 100, "deadline_handling": 0, "delivery_types": 0, "parentnode": self.testhelper.duck2000.id, }, ) self.assertEquals(response.status_code, 201) created = Assignment.objects.get(id=content["id"]) admins = created.admins.all() self.assertEquals(len(admins), 1) self.assertEquals(admins[0].username, "testadmin")
class TestRestListOrCreateSubjectRest(TestCase): def setUp(self): self.testhelper = TestHelper() self.testhelper.add( nodes="uni:admin(uniadmin)", subjects=[ "duck2000:admin(adminone,admintwo):ln(Something fancy)", "duck3000", "duck1000:admin(adminone)", "duck4000:admin(adminone,admintwo,singleadmin)", ], ) self.client = RestClient() self.url = "/devilry_subjectadmin/rest/subject/" self.testhelper.create_user("nobody") def _listas(self, username, **data): self.client.login(username=username, password="******") return self.client.rest_get(self.url, **data) def test_list(self): content, response = self._listas("adminone") self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 3) self.assertEquals(content[0]["short_name"], "duck1000") self.assertEquals(content[1]["short_name"], "duck2000") self.assertEquals(content[1]["long_name"], "Something fancy") self.assertEquals(content[2]["short_name"], "duck4000") self.assertEquals(set(content[0].keys()), set(["id", "parentnode", "etag", "short_name", "long_name"])) def test_list_singleadmin(self): content, response = self._listas("singleadmin") self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 1) self.assertEquals(content[0]["short_name"], "duck4000") def test_list_nonadmin(self): self.testhelper.create_user("otheruser") content, response = self._listas("otheruser") self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 0) def test_list_in_node(self): self.testhelper.add(nodes="othernode:admin(otheradmin)", subjects=["s1", "s2"]) content, response = self._listas("otheradmin", parentnode=self.testhelper.othernode.id) self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 2) shortnames = set([p["short_name"] for p in content]) self.assertEquals(shortnames, set(["s1", "s2"])) def _createas(self, username, data): self.client.login(username=username, password="******") return self.client.rest_post(self.url, data) def test_create(self): content, response = self._createas( "uniadmin", {"short_name": "test", "long_name": "Test", "admins": [], "parentnode": self.testhelper.uni.id} ) self.assertEquals(response.status_code, 201) self.assertEquals(content["long_name"], "Test") self.assertEquals(content["short_name"], "test") self.assertEquals(content["parentnode"], self.testhelper.uni.id) created = Subject.objects.get(id=content["id"]) self.assertEquals(created.short_name, "test") self.assertEquals(created.long_name, "Test") self.assertEquals(created.parentnode.id, self.testhelper.uni.id) admins = created.admins.all() self.assertEquals(len(admins), 0) def test_create_nobody(self): content, response = self._createas( "nobody", {"short_name": "test", "long_name": "Test", "admins": [], "parentnode": self.testhelper.uni.id} ) self.assertEquals(response.status_code, 403) self.assertEquals(content["detail"], "Permission denied") def test_create_admins(self): self.testhelper.create_user("testadmin") content, response = self._createas( "uniadmin", { "short_name": "test", "long_name": "Test", "admins": [{"id": self.testhelper.testadmin.id}], "parentnode": self.testhelper.uni.id, }, ) self.assertEquals(response.status_code, 201) created = Subject.objects.get(id=content["id"]) admins = created.admins.all() self.assertEquals(len(admins), 1) self.assertEquals(admins[0].username, "testadmin")
class TestRestListOrCreateSubjectRest(TestCase): def setUp(self): self.testhelper = TestHelper() self.testhelper.add(nodes='uni:admin(uniadmin)', subjects=['duck2000:admin(adminone,admintwo):ln(Something fancy)', 'duck3000', 'duck1000:admin(adminone)', 'duck4000:admin(adminone,admintwo,singleadmin)']) self.client = RestClient() self.url = '/devilry_subjectadmin/rest/subject/' self.testhelper.create_user('nobody') def _listas(self, username, **data): self.client.login(username=username, password='******') return self.client.rest_get(self.url, **data) def test_list(self): content, response = self._listas('adminone') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 3) self.assertEquals(content[0]['short_name'], 'duck1000') self.assertEquals(content[1]['short_name'], 'duck2000') self.assertEquals(content[1]['long_name'], 'Something fancy') self.assertEquals(content[2]['short_name'], 'duck4000') self.assertEquals(set(content[0].keys()), set(['id', 'parentnode', 'etag', 'short_name', 'long_name'])) def test_list_singleadmin(self): content, response = self._listas('singleadmin') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 1) self.assertEquals(content[0]['short_name'], 'duck4000') def test_list_nonadmin(self): self.testhelper.create_user('otheruser') content, response = self._listas('otheruser') self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 0) def test_list_in_node(self): self.testhelper.add(nodes='othernode:admin(otheradmin)', subjects=['s1', 's2']) content, response = self._listas('otheradmin', parentnode=self.testhelper.othernode.id) self.assertEquals(response.status_code, 200) self.assertEquals(len(content), 2) shortnames = set([p['short_name'] for p in content]) self.assertEquals(shortnames, set(['s1', 's2'])) def _createas(self, username, data): self.client.login(username=username, password='******') return self.client.rest_post(self.url, data) def test_create(self): content, response = self._createas('uniadmin', {'short_name': 'test', 'long_name': 'Test', 'admins': [], 'parentnode': self.testhelper.uni.id}) self.assertEquals(response.status_code, 201) self.assertEquals(content['long_name'], 'Test') self.assertEquals(content['short_name'], 'test') self.assertEquals(content['parentnode'], self.testhelper.uni.id) created = Subject.objects.get(id=content['id']) self.assertEquals(created.short_name, 'test') self.assertEquals(created.long_name, 'Test') self.assertEquals(created.parentnode.id, self.testhelper.uni.id) admins = created.admins.all() self.assertEquals(len(admins), 0) def test_create_nobody(self): content, response = self._createas('nobody', {'short_name': 'test', 'long_name': 'Test', 'admins': [], 'parentnode': self.testhelper.uni.id}) self.assertEquals(response.status_code, 403) self.assertEquals(content['detail'], 'Permission denied') def test_create_admins(self): self.testhelper.create_user('testadmin') content, response = self._createas('uniadmin', {'short_name': 'test', 'long_name': 'Test', 'admins': [{'id': self.testhelper.testadmin.id}], 'parentnode': self.testhelper.uni.id}) self.assertEquals(response.status_code, 201) created = Subject.objects.get(id=content['id']) admins = created.admins.all() self.assertEquals(len(admins), 1) self.assertEquals(admins[0].username, 'testadmin')