def test_grade_create_max_one_thesis_grade(self, mocked_method): self.client.login(username=self.teacher.username, password='******') self.data['grade_type'] = SubjectGrade.GradeTypes.THESIS self.catalog.wants_thesis = True self.catalog.save() grade = SubjectGradeFactory(catalog_per_subject=self.catalog, student=self.catalog.student, semester=1, academic_year=2020, grade_type=SubjectGrade.GradeTypes.THESIS) self.data['taken_at'] = date(2019, 11, 10) with patch('django.utils.timezone.now', return_value=timezone.datetime( 2019, 11, 11).replace(tzinfo=utc)) as mocked_method: response = self.client.post(self.build_url(self.catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data, { 'grade_type': [ 'There can be only one thesis grade per subject per semester.' ] }) grade.delete() grade = SubjectGradeFactory(catalog_per_subject=self.catalog, student=self.catalog.student, semester=2, academic_year=2020, grade_type=SubjectGrade.GradeTypes.THESIS) self.data['taken_at'] = date(2020, 4, 4) with patch('django.utils.timezone.now', return_value=timezone.datetime( 2020, 4, 5).replace(tzinfo=utc)) as mocked_method: response = self.client.post(self.build_url(self.catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data, { 'grade_type': [ 'There can be only one thesis grade per subject per semester.' ] }) grade.grade_type = SubjectGrade.GradeTypes.REGULAR grade.save() with patch('django.utils.timezone.now', return_value=timezone.datetime( 2020, 4, 5).replace(tzinfo=utc)) as mocked_method: response = self.client.post(self.build_url(self.catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_201_CREATED)
def test_bulk_create_absence_validate_student(self, timezone_mock): self.client.login(username=self.teacher.username, password='******') self.request_data['taken_at'] = date(2019, 9, 20) self.request_data['student_absences'][0]['student'] = 0 response = self.client.post(self.build_url(self.study_class.id, self.subject.id), data=self.request_data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data['student_absences'][0]['student'], ['Invalid pk "0" - object does not exist.']) # Not student in class student1 = UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, school_unit=self.school_unit) # Not enrolled student2 = UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, school_unit=self.school_unit, student_in_class=self.study_class) StudentCatalogPerSubjectFactory(student=student2, study_class=self.study_class, teacher=self.teacher, subject=self.subject, is_enrolled=False) # Not active student3 = UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, school_unit=self.school_unit, student_in_class=self.study_class, is_active=False) StudentCatalogPerSubjectFactory(student=student3, study_class=self.study_class, teacher=self.teacher, subject=self.subject) for student in [student1, student2, student3]: self.request_data['student_absences'][0]['student'] = student.id response = self.client.post(self.build_url(self.study_class.id, self.subject.id), data=self.request_data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data['student'], [f'Invalid pk "{student.id}" - object does not exist.'])
def test_user_profile_update_student_validations(self): self.client.login(username=self.principal.username, password='******') student = UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, school_unit=self.school_unit) url = self.build_url(student.id) self.student_data['educator_full_name'] = 'Educator' response = self.client.put(url, self.student_data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, ({'educator_full_name': [ 'Either email or phone number is required for the educator.' ]})) self.student_data['educator_email'] = '*****@*****.**' response = self.client.put(url, self.student_data) self.assertEqual(response.status_code, status.HTTP_200_OK) # Invalid personal_id_number del self.student_data['educator_full_name'] del self.student_data['educator_email'] for bad_data in ['32840', '249124395385039850', '123456789123a']: self.student_data['personal_id_number'] = bad_data response = self.client.put(url, self.student_data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'personal_id_number': ['Invalid format. Must be 13 digits, no spaces allowed.']}) # Birth date must be in the past next_year = timezone.now().year + 1 del self.student_data['personal_id_number'] self.student_data['birth_date'] = date(next_year, 1, 1) response = self.client.put(url, self.student_data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'birth_date': ['Birth date must be in the past.']})
def setUp(self): self.catalog.refresh_from_db() self.data = { 'grade1': 8, 'grade2': 8, 'taken_at': date(2020, 8, 21) }
def setUp(self): self.administrator.refresh_from_db() self.data = { 'use_phone_as_username': True, 'email': '*****@*****.**', 'phone_number': '+40700100200', 'full_name': 'New Name', 'email_notifications_enabled': True, 'sms_notifications_enabled': True, 'push_notifications_enabled': True, 'current_password': '******', 'new_password': '******', 'user_role': 'ADMINISTRATOR' } self.parent_data = { **self.data, 'address': 'address', 'user_role': 'PARENT' } self.student_data = { **self.data, 'address': 'address', 'personal_id_number': '1900203044858', 'birth_date': date(2000, 1, 1), 'user_role': 'STUDENT' }
def test_examination_grade_update_grade_in_the_future(self, mocked_method): self.client.login(username=self.teacher.username, password='******') self.data['taken_at'] = date(2020, 8, 23) response = self.client.put(self.build_url(self.create_2nd_exam_grade().id), self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'taken_at': ["Can't set grade dates in the future."]})
def test_bulk_create_grade_secondary_school_averages(self, timezone_mock): # This is for a subject with weekly hours count = 1 and no thesis (1st semester) self.client.login(username=self.teacher.username, password='******') self.request_data['taken_at'] = date(2019, 9, 20) response = self.client.post(self.build_url(self.study_class.id, self.subject.id), data=self.request_data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.refresh_objects_from_db([ self.catalog1, self.catalog2, self.catalog_per_year1, self.catalog_per_year2, self.study_class, self.school_stats ]) for catalog in [self.catalog1, self.catalog_per_year1]: self.assertEqual(catalog.avg_sem1, 6) self.assertIsNone(catalog.avg_sem2) self.assertIsNone(catalog.avg_annual) self.assertIsNone(catalog.avg_final) for catalog in [self.catalog2, self.catalog_per_year2]: self.assertIsNone(catalog.avg_sem1) self.assertIsNone(catalog.avg_sem2) self.assertIsNone(catalog.avg_annual) self.assertIsNone(catalog.avg_final) for obj in [self.study_class, self.school_stats]: self.assertEqual(obj.avg_sem1, 6) self.assertIsNone(obj.avg_sem2) self.assertIsNone(obj.avg_annual)
def test_bulk_create_absence_wrong_semester(self, timezone_mock): self.client.login(username=self.teacher.username, password='******') self.request_data['taken_at'] = date(2019, 9, 21) response = self.client.post(self.build_url(self.study_class.id, self.subject.id), data=self.request_data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data['taken_at'], ['The date cannot be in the first semester.'])
def setUp(self): self.refresh_objects_from_db( [self.student, self.catalog, self.catalog_per_year]) self.data = { 'grade': 10, 'grade_type': SubjectGrade.GradeTypes.REGULAR, 'taken_at': date(2020, 3, 3) }
def test_grade_create_grade_in_the_future(self, mocked_method): self.client.login(username=self.teacher.username, password='******') self.data['taken_at'] = date(2020, 4, 5) response = self.client.post(self.build_url(self.catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'taken_at': ["Can't set grade date in the future."]})
def setUp(self): self.refresh_objects_from_db([self.student, self.catalog]) self.data = { 'taken_at': date(2020, 8, 23), 'grade1': 10, 'grade2': 9, 'examination_type': ExaminationGrade.ExaminationTypes.WRITTEN, 'grade_type': ExaminationGrade.GradeTypes.SECOND_EXAMINATION, }
def test_current_academic_year_calendar_update_semester_validation(self): self.client.login(username=self.admin.username, password='******') other_calendar = AcademicYearCalendarFactory(academic_year=2019) self.data['first_semester']['id'] = other_calendar.first_semester.id response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, { 'first_semester': ['The semester must belong to the academic year.'] }) self.data['first_semester'][ 'id'] = self.academic_year_calendar.first_semester.id self.data['first_semester']['starts_at'] = self.data['first_semester'][ 'ends_at'] response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data, { 'first_semester': { 'starts_at': ['The start date must be before the end date.'] } }) self.data['first_semester']['starts_at'] = date(self.next_year, 1, 1) self.data['first_semester']['ends_at'] = date(self.next_year, 10, 10) self.data['second_semester']['starts_at'] = date(self.next_year, 5, 5) self.data['second_semester']['ends_at'] = date(self.next_year, 12, 12) response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data, { 'second_semester': [ 'Second semester must start after the end of the first semester.' ] }) self.data['first_semester']['starts_at'] = date(self.next_year, 1, 1) self.data['first_semester']['ends_at'] = date(self.next_year, 5, 5) self.data['second_semester']['starts_at'] = date(self.next_year, 6, 6) self.data['second_semester']['ends_at'] = date(self.next_year, 4, 4) response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data, { 'second_semester': { 'starts_at': ['The start date must be before the end date.'] } })
def test_create_absence_future_date(self, timezone_mock): self.client.login(username=self.teacher.username, password='******') self.request_data['taken_at'] = date(2019, 9, 21) response = self.client.post(self.build_url(self.catalog.id), data=self.request_data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data['taken_at'], ['The date cannot be in the future.'])
def setUp(self): self.academic_year_calendar = AcademicYearCalendarFactory( first_semester__starts_at=datetime(self.next_year, 1, 10), first_semester__ends_at=datetime(self.next_year, 4, 3), second_semester__starts_at=datetime(self.next_year, 9, 9), second_semester__ends_at=datetime(self.next_year, 12, 11)) self.data = { 'first_semester': { 'id': self.academic_year_calendar.first_semester.id, 'starts_at': date(self.next_year, 1, 1), 'ends_at': date(self.next_year, 4, 4), 'events': [] }, 'second_semester': { 'id': self.academic_year_calendar.second_semester.id, 'starts_at': date(self.next_year, 9, 9), 'ends_at': date(self.next_year, 12, 12), 'events': [] }, 'events': [] }
def test_bulk_create_grade_second_semester_success(self, timezone_mock): self.client.login(username=self.teacher.username, password='******') self.request_data['taken_at'] = date(2020, 4, 20) response = self.client.post(self.build_url(self.study_class.id, self.subject.id), data=self.request_data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertCountEqual(response.data.keys(), ['catalogs']) for catalogs in response.data['catalogs']: self.assertCountEqual(catalogs.keys(), self.expected_fields) self.check_data(2)
def test_grade_create_secondary_school_averages(self, mocked_method): # This is for a subject with weekly hours count = 1 and no thesis (1st semester) self.client.login(username=self.teacher.username, password='******') # Add a few more catalogs per subject for this student StudentCatalogPerSubjectFactory(student=self.student, study_class=self.study_class, avg_sem1=9) StudentCatalogPerSubjectFactory(student=self.student, study_class=self.study_class, is_enrolled=False) StudentCatalogPerSubjectFactory(student=self.student, study_class=self.study_class, is_exempted=True) # Add year catalog for a different student StudentCatalogPerYearFactory(study_class=self.study_class, avg_sem1=9) self.data['taken_at'] = date(2019, 11, 10) response = self.client.post(self.build_url(self.catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) # because the student doesn't have enough grades, the average shouldn't be computed yet self.catalog.refresh_from_db() self.assertIsNone(self.catalog.avg_sem1) self.assertIsNone(self.catalog.avg_sem2) self.assertIsNone(self.catalog.avg_annual) self.assertIsNone(self.catalog.avg_final) # Add another grade, so we can compute the average self.data['grade'] = 9 response = self.client.post(self.build_url(self.catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.refresh_objects_from_db([ self.catalog, self.catalog_per_year, self.study_class, self.school_stats ]) self.assertEqual(self.catalog.avg_sem1, 10) self.assertEqual(self.catalog_per_year.avg_sem1, 9.5) for catalog in [self.catalog, self.catalog_per_year]: self.assertIsNone(catalog.avg_sem2) self.assertIsNone(catalog.avg_annual) self.assertIsNone(catalog.avg_final) for obj in [self.study_class, self.school_stats]: self.assertEqual(obj.avg_sem1, 9.25) self.assertIsNone(obj.avg_sem2) self.assertIsNone(obj.avg_annual)
def test_examination_grade_create_differences_per_semester_success( self, mocked_method): self.client.login(username=self.teacher.username, password='******') self.data['grade_type'] = ExaminationGrade.GradeTypes.DIFFERENCE self.data['taken_at'] = date(2020, 9, 7) for examination_type in [ ExaminationGrade.ExaminationTypes.WRITTEN, ExaminationGrade.ExaminationTypes.ORAL ]: self.data['examination_type'] = examination_type for semester in [1, 2]: self.data['semester'] = semester response = self.client.post(self.build_url(self.catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertCountEqual(response.data.keys(), self.expected_fields) self.assertEqual(len(response.data['second_examination_grades']), 0) self.assertEqual(len(response.data['difference_grades_sem1']), 2) self.assertEqual(len(response.data['difference_grades_sem2']), 2) for examination_data in response.data[ 'second_examination_grades'] + response.data[ 'difference_grades_sem1'] + response.data[ 'difference_grades_sem2']: self.assertCountEqual(examination_data.keys(), self.examination_grade_fields) self.refresh_objects_from_db([ self.catalog, self.catalog_per_year, self.study_class, self.study_class.academic_program, self.school_stats, self.teacher, self.teacher.school_unit ]) for catalog in [self.catalog, self.catalog_per_year]: self.assertEqual(catalog.avg_sem1, 10) self.assertEqual(catalog.avg_sem2, 10) self.assertEqual(catalog.avg_annual, 10) self.assertEqual(catalog.avg_final, 10) for obj in [ self.study_class, self.study_class.academic_program, self.school_stats ]: self.assertEqual(obj.avg_annual, 10) self.assertEqual(self.teacher.last_change_in_catalog, timezone.now()) self.assertEqual(self.teacher.school_unit.last_change_in_catalog, timezone.now())
def test_examination_grade_update_difference_grade_success(self, mocked_method): self.client.login(username=self.teacher.username, password='******') self.create_difference_grade() grade = self.create_difference_grade(examination_type=ExaminationGrade.ExaminationTypes.ORAL) self.data['taken_at'] = date(2020, 9, 3) response = self.client.put(self.build_url(grade.id), self.data) self.assertEqual(response.status_code, status.HTTP_200_OK) self.check_data(response, grade) self.refresh_objects_from_db([self.catalog, self.catalog_per_year, self.study_class, self.study_class.academic_program, self.school_stats, self.teacher, self.teacher.school_unit]) for catalog in [self.catalog, self.catalog_per_year]: self.assertEqual(catalog.avg_annual, 9) self.assertEqual(catalog.avg_final, 9) for obj in [self.study_class, self.study_class.academic_program, self.school_stats]: self.assertEqual(obj.avg_annual, 9)
def test_examination_grade_create_differences_per_previous_year_success( self, mocked_method): self.client.login(username=self.teacher.username, password='******') study_class = StudyClassFactory(school_unit=self.school_unit, class_grade='IX', class_grade_arabic=9, academic_year=2019) catalog = StudentCatalogPerSubjectFactory(subject=self.subject, teacher=self.teacher, student=self.student, study_class=study_class) catalog_per_year = StudentCatalogPerYearFactory( student=self.student, study_class=study_class) school_stats = SchoolUnitStatsFactory(school_unit=self.school_unit, academic_year=2019) self.data['grade_type'] = ExaminationGrade.GradeTypes.DIFFERENCE self.data['taken_at'] = date(2020, 9, 7) response = self.client.post(self.build_url(catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.data['examination_type'] = ExaminationGrade.ExaminationTypes.ORAL response = self.client.post(self.build_url(catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(len(response.data['second_examination_grades']), 0) self.assertEqual(len(response.data['difference_grades_sem1']), 0) self.assertEqual(len(response.data['difference_grades_sem2']), 2) self.refresh_objects_from_db([ catalog, catalog_per_year, study_class, study_class.academic_program, school_stats, self.teacher, self.teacher.school_unit ]) for catalog in [catalog, catalog_per_year]: self.assertEqual(catalog.avg_annual, Decimal('9.5')) self.assertEqual(catalog.avg_final, Decimal('9.5')) for obj in [study_class, study_class.academic_program, school_stats]: self.assertEqual(obj.avg_annual, Decimal('9.5')) self.assertEqual(self.teacher.last_change_in_catalog, timezone.now()) self.assertEqual(self.teacher.school_unit.last_change_in_catalog, timezone.now())
def test_create_absence_first_semester_success(self, timezone_mock): self.client.login(username=self.teacher.username, password='******') self.request_data['taken_at'] = date(2019, 9, 20) response = self.client.post(self.build_url(self.catalog.id), data=self.request_data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertCountEqual(response.data.keys(), self.expected_fields) absence = SubjectAbsence.objects.first() self.assertEqual(absence.catalog_per_subject, self.catalog) self.assertEqual(absence.student, self.student) self.assertEqual(absence.subject_name, self.subject.name) self.assertEqual(absence.semester, 1) self.assertTrue(absence.is_founded) self.refresh_objects_from_db([ self.catalog, self.catalog_per_year, self.study_class, self.study_class.academic_program, self.teacher, self.school_unit, self.school_stats ]) for catalog in [self.catalog, self.catalog_per_year]: self.assertEqual(catalog.abs_count_sem1, 1) self.assertEqual(catalog.abs_count_sem2, 0) self.assertEqual(catalog.abs_count_annual, 1) self.assertEqual(catalog.founded_abs_count_sem1, 1) self.assertEqual(catalog.founded_abs_count_sem2, 0) self.assertEqual(catalog.founded_abs_count_annual, 1) self.assertEqual(catalog.unfounded_abs_count_sem1, 0) self.assertEqual(catalog.unfounded_abs_count_sem2, 0) self.assertEqual(catalog.unfounded_abs_count_annual, 0) for obj in [ self.study_class, self.study_class.academic_program, self.school_stats ]: self.assertEqual(obj.unfounded_abs_avg_sem1, 0) self.assertEqual(obj.unfounded_abs_avg_sem2, 0) self.assertEqual(obj.unfounded_abs_avg_annual, 0) self.assertEqual(self.teacher.last_change_in_catalog, timezone.now()) self.assertEqual(self.school_unit.last_change_in_catalog, timezone.now())
def test_examination_grade_create_difference_validations( self, mocked_method): self.client.login(username=self.teacher.username, password='******') self.data['grade_type'] = ExaminationGrade.GradeTypes.DIFFERENCE self.data['taken_at'] = date(2020, 9, 7) diff_grade = ExaminationGradeFactory( catalog_per_subject=self.catalog, student=self.catalog.student, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE, semester=1) response = self.client.post(self.build_url(self.catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data['semester'], [ "You cannot add difference grades for the whole year because " "you have difference grades for a semester in this catalog." ]) diff_grade.semester = None diff_grade.save() response = self.client.post(self.build_url(self.catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data['examination_type'], ["You already added a grade with this examination type."]) self.data['semester'] = 1 response = self.client.post(self.build_url(self.catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data['semester'], [ "You cannot add difference grades for a semester because " "you have difference grades for the whole year in this catalog." ]) diff_grade.semester = 1 diff_grade.save() response = self.client.post(self.build_url(self.catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data['examination_type'], ["You already added a grade with this examination type."])
def test_grade_create_highschool_averages(self, mocked_method): # This is for a required subject with weekly hours count = 3 and with thesis (2nd semester) self.study_class.class_grade = 'IX' self.study_class.class_grade_arabic = 9 self.study_class.save() ProgramSubjectThroughFactory(generic_academic_program=self.study_class. academic_program.generic_academic_program, subject=self.subject, weekly_hours_count=3) self.catalog.avg_sem1 = 10 self.catalog.wants_thesis = True self.catalog.save() for i in range(3): SubjectGradeFactory(student=self.student, catalog_per_subject=self.catalog, semester=2, grade=9) self.client.login(username=self.teacher.username, password='******') self.data['taken_at'] = date(2020, 4, 5) self.data['grade_type'] = SubjectGrade.GradeTypes.THESIS response = self.client.post(self.build_url(self.catalog.id), self.data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.refresh_objects_from_db([ self.catalog, self.catalog_per_year, self.study_class, self.study_class.academic_program, self.school_stats ]) for catalog in [self.catalog, self.catalog_per_year]: self.assertEqual(catalog.avg_sem1, 10) self.assertEqual(catalog.avg_sem2, 9) self.assertEqual(catalog.avg_annual, 9.5) self.assertEqual(catalog.avg_final, 9.5) for obj in [ self.study_class, self.study_class.academic_program, self.school_stats ]: self.assertEqual(obj.avg_sem1, 10) self.assertEqual(obj.avg_sem2, 9) self.assertEqual(obj.avg_annual, 9.5)
def test_bulk_create_absence_second_semester_success(self, timezone_mock): self.client.login(username=self.teacher.username, password='******') self.request_data['taken_at'] = date(2020, 4, 20) self.catalog2.is_exempted = True self.catalog2.save() response = self.client.post(self.build_url(self.study_class.id, self.subject.id), data=self.request_data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertCountEqual(response.data.keys(), ['catalogs']) for catalogs in response.data['catalogs']: self.assertCountEqual(catalogs.keys(), self.expected_fields) self.check_data(2) self.refresh_objects_from_db([self.catalog1, self.catalog2, self.catalog_per_year1, self.catalog_per_year2, self.study_class, self.study_class.academic_program, self.school_stats]) for catalog in [self.catalog1, self.catalog_per_year1]: self.assertEqual(catalog.abs_count_sem1, 0) self.assertEqual(catalog.abs_count_sem2, 2) self.assertEqual(catalog.abs_count_annual, 2) self.assertEqual(catalog.founded_abs_count_sem1, 0) self.assertEqual(catalog.founded_abs_count_sem2, 2) self.assertEqual(catalog.founded_abs_count_annual, 2) self.assertEqual(catalog.unfounded_abs_count_sem1, 0) self.assertEqual(catalog.unfounded_abs_count_sem2, 0) self.assertEqual(catalog.unfounded_abs_count_annual, 0) for catalog in [self.catalog2, self.catalog_per_year2]: self.assertEqual(catalog.abs_count_sem1, 0) self.assertEqual(catalog.abs_count_sem2, 1) self.assertEqual(catalog.abs_count_annual, 1) self.assertEqual(catalog.founded_abs_count_sem1, 0) self.assertEqual(catalog.founded_abs_count_sem2, 0) self.assertEqual(catalog.founded_abs_count_annual, 0) self.assertEqual(catalog.unfounded_abs_count_sem1, 0) self.assertEqual(catalog.unfounded_abs_count_sem2, 1) self.assertEqual(catalog.unfounded_abs_count_annual, 1) for obj in [self.study_class, self.study_class.academic_program, self.school_stats]: self.assertEqual(obj.unfounded_abs_avg_sem1, 0) self.assertEqual(obj.unfounded_abs_avg_sem2, 0) self.assertEqual(obj.unfounded_abs_avg_annual, 0)
def setUp(self): self.admin_data = { 'Name': 'John Doe', 'Email address': '*****@*****.**', 'Use phone as username': '******', 'Phone number': '+40712999666', 'User role': 'Administrator' } self.principal_data = { **self.admin_data, 'User role': 'School Principal', 'Phone number': '+40712999667', } self.teacher_data = { **self.admin_data, 'User role': 'Teacher', 'Phone number': '+40712999668', } self.student_data = { **self.admin_data, 'Address': 'address', 'Personal id number': '1900203099032', 'Birth date': date(2000, 1, 1), 'User role': 'Student', 'Educator name': 'Educator', 'Educator phone number': '+40712333444', 'Educator email address': '*****@*****.**', } self.parent_data = { **self.admin_data, 'Address': 'Address', 'User role': 'Parent', 'Phone number': '+40712999669', }
def test_grade_update_secondary_school_averages(self, mocked_method): # This is for a subject with weekly hours count = 1 and no thesis (1st semester) self.client.login(username=self.teacher.username, password='******') # Add a few more catalogs per subject for this student StudentCatalogPerSubjectFactory(student=self.student, study_class=self.study_class, avg_sem1=9) StudentCatalogPerSubjectFactory(student=self.student, study_class=self.study_class, avg_sem1=10) SubjectGradeFactory(student=self.student, catalog_per_subject=self.catalog, semester=1, grade=9) grade = self.create_grade(semester=1) self.catalog.avg_sem1 = 10 self.catalog.save() self.data['taken_at'] = date(2019, 11, 10) response = self.client.put(self.build_url(grade.id), self.data) self.assertEqual(response.status_code, status.HTTP_200_OK) self.refresh_objects_from_db([ self.catalog, self.catalog_per_year, self.study_class, self.school_stats ]) self.assertEqual(self.catalog.avg_sem1, 9) self.assertIsNone(self.catalog.avg_sem2) self.assertIsNone(self.catalog.avg_annual) self.assertIsNone(self.catalog.avg_final) self.assertIsNone(self.catalog_per_year.avg_final) for obj in [ self.catalog_per_year, self.study_class, self.school_stats ]: self.assertEqual(obj.avg_sem1, Decimal('9.33')) self.assertIsNone(obj.avg_sem2) self.assertIsNone(obj.avg_annual)
class UserProfileImportTestCase(CommonAPITestCase): @classmethod def setUpTestData(cls): cls.admin = UserProfileFactory( user_role=UserProfile.UserRoles.ADMINISTRATOR) cls.school_unit = RegisteredSchoolUnitFactory() cls.principal = cls.school_unit.school_principal cls.principal.school_unit = cls.school_unit cls.principal.save() cls.url = reverse('users:import-users') cls.file_name = 'file.csv' def setUp(self): self.admin_data = { 'Name': 'John Doe', 'Email address': '*****@*****.**', 'Use phone as username': '******', 'Phone number': '+40712999666', 'User role': 'Administrator' } self.principal_data = { **self.admin_data, 'User role': 'School Principal', 'Phone number': '+40712999667', } self.teacher_data = { **self.admin_data, 'User role': 'Teacher', 'Phone number': '+40712999668', } self.student_data = { **self.admin_data, 'Address': 'address', 'Personal id number': '1900203099032', 'Birth date': date(2000, 1, 1), 'User role': 'Student', 'Educator name': 'Educator', 'Educator phone number': '+40712333444', 'Educator email address': '*****@*****.**', } self.parent_data = { **self.admin_data, 'Address': 'Address', 'User role': 'Parent', 'Phone number': '+40712999669', } @staticmethod def create_file(file_name): file = io.StringIO() file.name = file_name return file def get_response(self, file): file.seek(0) response = self.client.post(self.url, data={'file': file}, format='multipart') return response def test_user_profile_import_unauthenticated(self): response = self.client.post(self.url) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) @data(UserProfile.UserRoles.TEACHER, UserProfile.UserRoles.STUDENT, UserProfile.UserRoles.PARENT) def test_user_profile_import_wrong_user_type(self, user_role): school_unit = RegisteredSchoolUnitFactory() profile = UserProfileFactory(user_role=user_role, school_unit=school_unit) self.client.login(username=profile.username, password='******') response = self.client.post(self.url) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) @data('application/json', 'text/html', 'text/csv', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') def test_user_profile_import_wrong_content_type(self, content_type): self.client.login(username=self.admin, password='******') file = self.create_file(self.file_name) file.write('aaa') response = self.client.post(self.url, data={'file': file}, content_type=content_type) self.assertEqual(response.status_code, status.HTTP_415_UNSUPPORTED_MEDIA_TYPE) self.assertEqual( response.data, {'detail': f'Unsupported media type "{content_type}" in request.'}) @data('file.txt', 'file.docx', 'file.csvx') def test_user_profile_import_invalid_extension(self, file_name): self.client.login(username=self.admin.username, password='******') file = self.create_file(file_name) file.write('aaa') response = self.get_response(file) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'file': ['File must be csv.']}) def test_user_profile_import_invalid_file(self): # No file at all self.client.login(username=self.admin.username, password='******') no_file_sent_error = {'file': ['No file was submitted.']} response = self.client.post(self.url, format='multipart') self.assertEqual(response.data, no_file_sent_error) # Wrong key file = self.create_file(self.file_name) response = self.client.post(self.url, {'wrong_file': file}, format='multipart') self.assertEqual(response.data, no_file_sent_error) # Wrong boundary request_data = encode_multipart('==boundary', {'file': file}) content_type = 'multipart/form-data; boundary=WrongBoundary' response = self.client.post(self.url, request_data, content_type=content_type) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, no_file_sent_error) @data('file', 'file.ext.ext', 'file()') def test_user_profile_import_invalid_file_name(self, file_name): self.client.login(username=self.admin.username, password='******') file = self.create_file(file_name) file.write('aaa') response = self.get_response(file) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'non_field_errors': ['Invalid file name.']}) @data( ('admin_data', ['Name', 'Use phone as username']), ('principal_data', ['Name', 'Use phone as username']), ('teacher_data', ['Name', 'Use phone as username']), ('parent_data', ['Name', 'Use phone as username']), ('student_data', ['Name', 'Use phone as username']), ) @unpack def test_user_profile_import_missing_fields(self, data_dict, required_fields): user = self.admin if data_dict in ['admin_data', 'principal_data' ] else self.principal self.client.login(username=user.username, password='******') request_data = getattr(self, data_dict) file = self.create_file(self.file_name) writer = csv.DictWriter(file, fieldnames=request_data.keys()) writer.writeheader() row = { field: request_data[field] for field in request_data.keys() if field not in required_fields } writer.writerow(row) response = self.get_response(file) self.assertEqual(response.status_code, status.HTTP_200_OK) errors = response.data['errors'][1] self.assertCountEqual(errors.keys(), required_fields) for key, value in errors.items(): self.assertEqual(value, 'This field is required.') @data( (UserProfile.UserRoles.ADMINISTRATOR, ['admin_data', 'principal_data' ]), (UserProfile.UserRoles.PRINCIPAL, ['teacher_data', 'parent_data', 'student_data']), ) @unpack def test_user_profile_import_success(self, user_role, data_dictionaries): self.client.login( username=UserProfile.objects.get(user_role=user_role).username, password='******') old_count = UserProfile.objects.count() data_dictionaries = [ getattr(self, data_dict) for data_dict in data_dictionaries ] keys = set() for data_dict in data_dictionaries: keys.update(data_dict.keys()) file = self.create_file(self.file_name) writer = csv.DictWriter(file, fieldnames=keys) writer.writeheader() for data_dict in data_dictionaries: writer.writerow(data_dict) response = self.get_response(file) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data['errors']), 0) self.assertEqual( response.data['report'], f'{len(data_dictionaries)} out of {len(data_dictionaries)} users saved successfully.' ) self.assertEqual(UserProfile.objects.count() - old_count, len(data_dictionaries)) @data(( 'Email address', ['invalid_email', 'invalid@email'], "Invalid format. Must be 150 characters at most and in the format [email protected]" ), ('Phone number', [ 'letters', '0000', '++40890092' ], "Invalid format. Must be minimum 10, maximum 20 digits or +."), ( 'User role', ['', '1', 'Invalid'], 'Must be one of the following options: Administrator, Principal, Teacher, Parent or Student.' ), ('Educator email address', [ 'invalid_email', 'invalid@email' ], "Invalid format. Must be 150 characters at most and in the format [email protected]" ), ('Educator phone number', ['letters', '0000', '++40890092'], "Invalid format. Must be minimum 10, maximum 20 digits or +."), ('Personal id number', ['letters', '0000', '1233444556678889990'], 'Invalid format. Must be 13 digits, no spaces allowed.'), ('Birth date', [date(3000, 1, 1) ], 'Birth date must be in the past.'), ('Birth date', ['2000-01-02', '20-20-20000' ], 'Invalid date format. Must be DD-MM-YYYY.'), ('Use phone as username', ['true', 'True' ], 'Must be either yes or no.')) @unpack def test_user_profile_import_validations(self, field, invalid_data, expected_error): self.client.login(username=self.principal.username, password='******') row = self.student_data for invalid_attr in invalid_data: row[field] = invalid_attr file = self.create_file(self.file_name) writer = csv.DictWriter(file, fieldnames=self.student_data.keys()) writer.writeheader() writer.writerow(row) response = self.get_response(file) self.assertEqual(response.status_code, status.HTTP_200_OK) errors = response.data['errors'][1] self.assertEqual(len(errors), 1) self.assertEqual(response.data['report'], '0 out of 1 user saved successfully.') self.assertEqual(errors[field], expected_error) def test_user_profile_import_educator_validation(self): self.client.login(username=self.principal.username, password='******') self.student_data['Educator name'] = 'Educator' self.student_data['Educator phone number'] = '' self.student_data['Educator email address'] = '' file = self.create_file(self.file_name) writer = csv.DictWriter(file, fieldnames=self.student_data.keys()) writer.writeheader() writer.writerow(self.student_data) response = self.get_response(file) self.assertEqual(response.status_code, status.HTTP_200_OK) errors = response.data['errors'][1] self.assertEqual(len(errors), 1) self.assertEqual( errors['Educator name'], 'Either email or phone number is required for the educator.') @data('yes', 'no') def test_user_profile_import_username_validation(self, use_phone_as_username): self.client.login(username=self.admin.username, password='******') self.admin_data['Use phone as username'] = use_phone_as_username file = self.create_file(self.file_name) writer = csv.DictWriter(file, fieldnames=self.admin_data.keys()) writer.writeheader() writer.writerow(self.admin_data) response = self.get_response(file) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data['errors']), 0) username = self.admin_data[ 'Phone number'] if use_phone_as_username == 'yes' else self.admin_data[ 'Email address'] self.assertTrue(UserProfile.objects.filter(username=username).exists()) @data((UserProfile.UserRoles.ADMINISTRATOR, ['student_data', 'parent_data', 'teacher_data']), (UserProfile.UserRoles.PRINCIPAL, ['admin_data', 'principal_data'])) @unpack def test_user_profile_import_invalid_user_role(self, request_user_role, data_dictionaries): self.client.login(username=UserProfile.objects.get( user_role=request_user_role).username, password='******') for data_dict in data_dictionaries: file = self.create_file(self.file_name) writer = csv.DictWriter(file, fieldnames=self.student_data.keys()) writer.writeheader() writer.writerow(getattr(self, data_dict)) response = self.get_response(file) self.assertEqual(response.status_code, status.HTTP_200_OK) errors = response.data['errors'][1] self.assertEqual(len(errors), 1) self.assertEqual( errors['User role'], 'You don\'t have permission to create a user with this role.') @data((UserProfile.UserRoles.ADMINISTRATOR, 'admin_data'), (UserProfile.UserRoles.PRINCIPAL, 'principal_data'), (UserProfile.UserRoles.PARENT, 'parent_data'), (UserProfile.UserRoles.TEACHER, 'teacher_data')) @unpack def test_user_profile_import_extra_fields(self, user_role, data_dict): # Check that any supplied fields that don't belong to the user role are ignored user = self.admin if data_dict in ['admin_data', 'principal_data' ] else self.principal self.client.login(username=user.username, password='******') data_dict = getattr(self, data_dict) self.student_data['User role'] = data_dict['User role'] self.student_data['Phone number'] = data_dict['Phone number'] fieldnames = self.student_data.keys() file = self.create_file(self.file_name) writer = csv.DictWriter(file, fieldnames=fieldnames) writer.writeheader() writer.writerow(self.student_data) response = self.get_response(file) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data['errors']), 0) username = data_dict['Phone number'] if user_role in [ UserProfile.UserRoles.PARENT, UserProfile.UserRoles.TEACHER ]: username = '******'.format(self.principal.school_unit_id, username) user = UserProfile.objects.get(username=username) for field in [ 'Birth date', 'Educator phone number', 'Educator email', 'Educator name', 'Personal id number' ]: self.assertIsNone(getattr(user, field, None)) @data(('Name', 180, 181 * 'a'), ('Email address', 150, 145 * 'a' + '@gmail.com'), ('Educator email address', 150, 145 * 'a' + '@gmail.com'), ('Educator name', 180, 181 * 'a')) @unpack def test_user_profile_import_max_length(self, field_name, max_length, invalid_value): self.client.login(username=self.principal.username, password='******') self.student_data[field_name] = invalid_value fieldnames = self.student_data.keys() file = self.create_file(self.file_name) writer = csv.DictWriter(file, fieldnames=fieldnames) writer.writeheader() writer.writerow(self.student_data) response = self.get_response(file) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data['errors']), 1) self.assertEqual(response.data['errors'][1][field_name], f'Write maximum {max_length} characters.')
class UserProfileMyAccountUpdateTestCase(CommonAPITestCase): @classmethod def setUpTestData(cls): cls.url = reverse('users:my-account') cls.administrator = UserProfileFactory(user_role=UserProfile.UserRoles.ADMINISTRATOR) cls.principal = UserProfileFactory(user_role=UserProfile.UserRoles.PRINCIPAL) cls.teacher = UserProfileFactory(user_role=UserProfile.UserRoles.TEACHER) cls.parent = UserProfileFactory(user_role=UserProfile.UserRoles.PARENT) cls.student = UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT) cls.registered_school_unit = RegisteredSchoolUnitFactory(school_principal=cls.principal) for user in UserProfile.objects.exclude(user_role=UserProfile.UserRoles.ADMINISTRATOR): user.school_unit = cls.registered_school_unit user.save() def setUp(self): self.administrator.refresh_from_db() self.data = { 'use_phone_as_username': True, 'email': '*****@*****.**', 'phone_number': '+40700100200', 'full_name': 'New Name', 'email_notifications_enabled': True, 'sms_notifications_enabled': True, 'push_notifications_enabled': True, 'current_password': '******', 'new_password': '******', 'user_role': 'ADMINISTRATOR' } self.parent_data = { **self.data, 'address': 'address', 'user_role': 'PARENT' } self.student_data = { **self.data, 'address': 'address', 'personal_id_number': '1900203044858', 'birth_date': date(2000, 1, 1), 'user_role': 'STUDENT' } def test_user_profile_my_account_update_unauthenticated(self): response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) @data( UserProfile.UserRoles.ADMINISTRATOR, UserProfile.UserRoles.PRINCIPAL, UserProfile.UserRoles.TEACHER, UserProfile.UserRoles.STUDENT, UserProfile.UserRoles.PARENT ) def test_user_profile_my_account_update_required_fields(self, user_role): self.client.login(username=UserProfile.objects.get(user_role=user_role).username, password='******') required_fields = [ 'phone_number', 'use_phone_as_username', 'full_name', 'email_notifications_enabled', 'push_notifications_enabled', 'sms_notifications_enabled' ] for field in required_fields: data_to_send = { field_name: self.data.get(field_name) for field_name in required_fields if field_name != field } data_to_send['user_role'] = user_role response = self.client.put(self.url, data_to_send) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {field: ['This field is required.']}) @data( (UserProfile.UserRoles.ADMINISTRATOR, ['id', 'full_name', 'user_role', 'email', 'phone_number', 'use_phone_as_username', 'email_notifications_enabled', 'sms_notifications_enabled', 'push_notifications_enabled', 'school_unit']), (UserProfile.UserRoles.PRINCIPAL, ['id', 'full_name', 'user_role', 'email', 'phone_number', 'use_phone_as_username', 'email_notifications_enabled', 'sms_notifications_enabled', 'push_notifications_enabled', 'school_unit']), (UserProfile.UserRoles.TEACHER, ['id', 'full_name', 'user_role', 'email', 'phone_number', 'use_phone_as_username', 'email_notifications_enabled', 'sms_notifications_enabled', 'push_notifications_enabled', 'school_unit']), (UserProfile.UserRoles.PARENT, ['id', 'full_name', 'user_role', 'email', 'phone_number', 'use_phone_as_username', 'email_notifications_enabled', 'sms_notifications_enabled', 'push_notifications_enabled', 'address', 'school_unit', 'children']), (UserProfile.UserRoles.STUDENT, ['id', 'full_name', 'user_role', 'email', 'phone_number', 'use_phone_as_username', 'email_notifications_enabled', 'sms_notifications_enabled', 'push_notifications_enabled', 'address', 'class_grade', 'class_letter', 'personal_id_number', 'birth_date', 'school_unit']) ) @unpack def test_user_profile_my_account_update_expected_response_fields(self, user_role, expected_fields): profile = UserProfile.objects.get(user_role=user_role) self.client.login(username=profile.username, password='******') if user_role == UserProfile.UserRoles.PARENT: data_to_send = self.parent_data elif user_role == UserProfile.UserRoles.STUDENT: data_to_send = self.student_data else: data_to_send = self.data data_to_send['user_role'] = user_role.upper() response = self.client.put(self.url, data_to_send) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertCountEqual(response.data.keys(), expected_fields) def test_user_profile_my_account_update_password_validations(self): self.client.login(username=self.administrator.username, password='******') self.data['new_password'] = '' response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'new_password': ['This field is required.']}) for new_password in ['a' * 5, 'a' * 129, 'abcdefg h']: self.data['new_password'] = new_password response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'new_password': ['Invalid format. Must be minimum 6, maximum 128 characters, no spaces allowed.']}) self.data['new_password'] = '******' self.data['current_password'] = '' response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'current_password': ['This field is required.']}) self.data['current_password'] = '******' response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'current_password': ["Does not match the user's current password."]}) def test_user_profile_my_account_update_success(self): self.client.login(username=self.administrator.username, password='******') response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_200_OK) self.refresh_objects_from_db([self.administrator, self.administrator.user]) for field, value in self.data.items(): if field not in ['user_role', 'new_password', 'current_password']: self.assertEqual(value, getattr(self.administrator, field)) self.assertTrue(self.administrator.user.check_password(self.data['new_password'])) self.assertEqual(self.administrator.username, self.data['phone_number']) def test_user_profile_my_account_update_username_validations(self): self.client.login(username=self.administrator.username, password='******') self.data['use_phone_as_username'] = False self.data['email'] = self.principal.email response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'username': ['This username is already associated with another account.']}) self.data['use_phone_as_username'] = True self.data['email'] = '*****@*****.**' del self.data['phone_number'] response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'phone_number': ['This field is required.']}) self.data['use_phone_as_username'] = False self.data['email'] = '' response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'email': ['This field is required.']}) @data( ('email', ['invalid_email', 'invalid@email'], ["Enter a valid email address."]), ('phone_number', ['letters', '0000', '++40890092'], ["Invalid format. Must be minimum 10, maximum 20 digits or +."]), ('personal_id_number', ['letters', '0000', '1233444556678889990'], ['Invalid format. Must be 13 digits, no spaces allowed.']), ('birth_date', [date(3000, 1, 1)], ['Birth date must be in the past.']), ('birth_date', ['2000-01-02', '20-20-20000'], ['Date has wrong format. Use one of these formats instead: DD-MM-YYYY.']), ) @unpack def test_user_profile_my_account_update_validations(self, field, values, expected_error): self.client.login(username=self.student.username, password='******') for value in values: self.data[field] = value response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data[field], expected_error)
def test_current_academic_year_calendar_update_success(self): self.client.login(username=self.admin.username, password='******') response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_200_OK) self.academic_year_calendar.refresh_from_db() expected_fields = [ 'first_semester', 'second_semester', 'academic_year', 'events' ] self.assertCountEqual(expected_fields, response.data.keys()) semester_expected_fields = ['id', 'starts_at', 'ends_at', 'events'] self.assertCountEqual(semester_expected_fields, response.data['first_semester']) self.assertCountEqual(semester_expected_fields, response.data['second_semester']) for semester in ['first_semester', 'second_semester']: self.assertEqual( getattr(self.academic_year_calendar, semester).starts_at.strftime(settings.DATE_FORMAT), self.data[semester]['starts_at']) # Try to add an event self.data['first_semester']['events'] = [{ 'starts_at': date(self.next_year, 2, 2), 'ends_at': date(self.next_year, 2, 3), 'event_type': SchoolEvent.EventTypes.LEGAL_PUBLIC_HOLIDAY }] response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_200_OK) event = self.academic_year_calendar.first_semester.school_events.first( ) self.assertEqual(event.starts_at, event.starts_at) # Update it self.data['first_semester']['events'] = [{ 'id': event.id, 'starts_at': date(self.next_year, 2, 2), 'ends_at': date(self.next_year, 2, 3), 'event_type': SchoolEvent.EventTypes.SPRING_HOLIDAY }] response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_200_OK) event.refresh_from_db() self.assertEqual(event.event_type, SchoolEvent.EventTypes.SPRING_HOLIDAY) # Add new ones self.data['first_semester']['events'] += [{ 'starts_at': date(self.next_year, 2, 6), 'ends_at': date(self.next_year, 2, 10), 'event_type': SchoolEvent.EventTypes.LEGAL_PUBLIC_HOLIDAY }, { 'starts_at': date(self.next_year, 3, 2), 'ends_at': date(self.next_year, 3, 3), 'event_type': SchoolEvent.EventTypes.LEGAL_PUBLIC_HOLIDAY }] response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( self.academic_year_calendar.first_semester.school_events.count(), 3) # Remove one of them self.data['first_semester']['events'].pop() response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( self.academic_year_calendar.first_semester.school_events.count(), 2)
def test_current_academic_year_calendar_update_year_events_validation( self): self.client.login(username=self.admin.username, password='******') for bad_data in [[{ 'starts_at': date(self.next_year, 12, 21), 'ends_at': date(self.next_year, 12, 23), 'event_type': SchoolEvent.EventTypes.CORIGENTE }, { 'starts_at': date(self.next_year, 12, 22), 'ends_at': date(self.next_year, 12, 25), 'event_type': SchoolEvent.EventTypes.CORIGENTE }], [{ 'starts_at': date(self.next_year, 12, 23), 'ends_at': date(self.next_year, 12, 25), 'event_type': SchoolEvent.EventTypes.DIFERENTE }, { 'starts_at': date(self.next_year, 12, 23), 'ends_at': date(self.next_year, 12, 26), 'event_type': SchoolEvent.EventTypes.CORIGENTE }], [{ 'starts_at': date(self.next_year, 12, 22), 'ends_at': date(self.next_year, 12, 25), 'event_type': SchoolEvent.EventTypes.DIFERENTE }, { 'starts_at': date(self.next_year, 12, 23), 'ends_at': date(self.next_year, 12, 24), 'event_type': SchoolEvent.EventTypes.DIFERENTE }]]: self.data['events'] = bad_data response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'events': ['Events cannot overlap.']})
def test_current_academic_year_calendar_update_semester_events_validation( self): self.client.login(username=self.admin.username, password='******') for bad_data in [[{ 'starts_at': date(self.next_year, 1, 2), 'ends_at': date(self.next_year, 3, 3), 'event_type': SchoolEvent.EventTypes.SPRING_HOLIDAY }, { 'starts_at': date(self.next_year, 2, 5), 'ends_at': date(self.next_year, 3, 2), 'event_type': SchoolEvent.EventTypes.LEGAL_PUBLIC_HOLIDAY }], [{ 'starts_at': date(self.next_year, 2, 2), 'ends_at': date(self.next_year, 3, 3), 'event_type': SchoolEvent.EventTypes.SPRING_HOLIDAY }, { 'starts_at': date(self.next_year, 3, 3), 'ends_at': date(self.next_year, 4, 1), 'event_type': SchoolEvent.EventTypes.LEGAL_PUBLIC_HOLIDAY }], [{ 'starts_at': date(self.next_year, 2, 2), 'ends_at': date(self.next_year, 2, 5), 'event_type': SchoolEvent.EventTypes.SPRING_HOLIDAY }, { 'starts_at': date(self.next_year, 2, 3), 'ends_at': date(self.next_year, 2, 4), 'event_type': SchoolEvent.EventTypes.LEGAL_PUBLIC_HOLIDAY }]]: self.data['first_semester']['events'] = bad_data response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data, {'events': ['Events cannot overlap.']}) # CORIGENTE and DIFERENTE can't be added inside the semester for event_type in [ SchoolEvent.EventTypes.CORIGENTE, SchoolEvent.EventTypes.DIFERENTE ]: self.data['first_semester']['events'] = [{ 'starts_at': date(self.next_year, 3, 3), 'ends_at': date(self.next_year, 4, 4), 'event_type': event_type }] response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data, { 'first_semester': { 'events': [ f'{event_type.label} events cannot be inside semesters.' ] } }) # SECOND_SEMESTER_END_IX_XI_FILIERA_TEHNOLOGICA must be between second semester start and the end of the school year self.data['first_semester']['events'] = [] self.data['second_semester']['events'] = [{ 'starts_at': date(self.next_year, 5, 5), 'ends_at': date(self.next_year, 5, 6), 'event_type': SchoolEvent.EventTypes. SECOND_SEMESTER_END_IX_XI_FILIERA_TEHNOLOGICA }] response = self.client.put(self.url, self.data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data, { 'events': { 'starts_at': "Second semester end for Filiera Tehnologica" " must be between the second semester's start and the end of" " the current academic year." } })