def test_study_class_partially_update_move_student_from_different_school(self): self.client.login(username=self.principal.username, password='******') self.new_student.labels.add( LabelFactory(text=TRANSFERRED_LABEL, is_label_for_transfers_between_schools=True) ) another_school_unit = RegisteredSchoolUnitFactory() another_school_profile = UserProfileFactory(school_unit=another_school_unit, full_name=self.new_student.full_name, username='******'.format(another_school_unit.id, self.new_student.email), email=self.new_student.email, phone_number=self.new_student.phone_number, user_role=UserProfile.UserRoles.STUDENT) prev_study_class = StudyClassFactory(school_unit=self.school_unit, class_master=self.teacher1, academic_program=self.academic_program, class_grade='IX', class_grade_arabic=9, class_letter='A', academic_year=self.calendar.academic_year - 1) TeacherClassThroughFactory(study_class=prev_study_class, teacher=self.teacher1, subject=self.coordination_subject, is_class_master=True) TeacherClassThroughFactory(study_class=prev_study_class, teacher=self.teacher1, subject=self.subject1, is_class_master=True) TeacherClassThroughFactory(study_class=prev_study_class, teacher=self.teacher2, subject=self.subject2, is_class_master=True, is_optional_subject=True) student_prev_study_class = StudyClassFactory(school_unit=another_school_unit, class_grade='IX', class_grade_arabic=9, academic_year=self.calendar.academic_year - 1) StudentCatalogPerYearFactory(student=another_school_profile, study_class=student_prev_study_class, avg_sem1=9, avg_sem2=9, avg_annual=9, avg_final=9) catalog1 = StudentCatalogPerSubjectFactory(student=another_school_profile, study_class=student_prev_study_class, subject=self.coordination_subject, avg_sem1=8, avg_sem2=8, avg_annual=8, avg_final=8) SubjectGradeFactory(student=another_school_profile, catalog_per_subject=catalog1, grade=8) SubjectAbsenceFactory(student=another_school_profile, catalog_per_subject=catalog1, is_founded=True) catalog2 = StudentCatalogPerSubjectFactory(student=another_school_profile, study_class=student_prev_study_class, subject=self.subject2, avg_sem1=10, avg_sem2=10, avg_annual=10, avg_final=10) ExaminationGradeFactory(student=another_school_profile, catalog_per_subject=catalog2) self.request_data = { "new_students": [self.new_student.id] } response = self.client.patch(self.build_url(self.study_class.id), self.request_data) self.assertEqual(response.status_code, status.HTTP_200_OK) catalog_per_year = StudentCatalogPerYear.objects.get(student=self.new_student, study_class=prev_study_class) for average in [catalog_per_year.avg_sem1, catalog_per_year.avg_sem2, catalog_per_year.avg_annual, catalog_per_year.avg_final]: self.assertEqual(average, 9) new_catalog1 = StudentCatalogPerSubject.objects.get(student=self.new_student, study_class=prev_study_class, subject=self.coordination_subject, teacher=self.teacher1) for average in [new_catalog1.avg_sem1, new_catalog1.avg_sem2, new_catalog1.avg_annual, new_catalog1.avg_final]: self.assertEqual(average, 8) self.assertEqual(new_catalog1.grades.count(), 1) self.assertEqual(new_catalog1.absences.count(), 1) new_catalog2 = StudentCatalogPerSubject.objects.get(student=self.new_student, study_class=prev_study_class, subject=self.subject2, teacher=self.teacher2) for average in [new_catalog2.avg_sem1, new_catalog2.avg_sem2, new_catalog2.avg_annual, new_catalog2.avg_final]: self.assertEqual(average, 10) self.assertEqual(new_catalog2.examination_grades.count(), 1) new_catalog3 = StudentCatalogPerSubject.objects.get(student=self.new_student, study_class=prev_study_class, subject=self.subject1, teacher=self.teacher1) for average in [new_catalog3.avg_sem1, new_catalog3.avg_sem2, new_catalog3.avg_annual, new_catalog3.avg_final]: self.assertEqual(average, None)
def setUpTestData(cls): cls.calendar = AcademicYearCalendarFactory() cls.school_unit = RegisteredSchoolUnitFactory() cls.school_stats = SchoolUnitStatsFactory(school_unit=cls.school_unit) cls.class_master = UserProfileFactory( user_role=UserProfile.UserRoles.TEACHER, school_unit=cls.school_unit) cls.study_class = StudyClassFactory(school_unit=cls.school_unit, class_master=cls.class_master) cls.subject = SubjectFactory() ProgramSubjectThroughFactory( academic_program=cls.study_class.academic_program, subject=cls.subject, weekly_hours_count=1, class_grade=cls.study_class.class_grade, class_grade_arabic=cls.study_class.class_grade_arabic) cls.student = UserProfileFactory( user_role=UserProfile.UserRoles.STUDENT, school_unit=cls.school_unit, student_in_class=cls.study_class) cls.teacher = UserProfileFactory( user_role=UserProfile.UserRoles.TEACHER, school_unit=cls.school_unit) TeacherClassThroughFactory(teacher=cls.teacher, study_class=cls.study_class, is_class_master=False, subject=cls.subject) cls.catalog = StudentCatalogPerSubjectFactory( student=cls.student, study_class=cls.study_class, teacher=cls.teacher, subject=cls.subject, abs_count_sem1=1, abs_count_annual=1, unfounded_abs_count_sem1=1, unfounded_abs_count_annual=1) cls.catalog_per_year = StudentCatalogPerYearFactory( student=cls.student, study_class=cls.study_class, abs_count_sem1=1, abs_count_annual=1, unfounded_abs_count_sem1=1, unfounded_abs_count_annual=1) cls.absence = SubjectAbsenceFactory(student=cls.student, catalog_per_subject=cls.catalog) cls.expected_fields = [ 'id', 'student', 'avg_sem1', 'avg_sem2', 'avg_annual', 'avg_after_2nd_examination', 'abs_count_sem1', 'abs_count_sem2', 'abs_count_annual', 'founded_abs_count_sem1', 'founded_abs_count_sem2', 'founded_abs_count_annual', 'unfounded_abs_count_sem1', 'unfounded_abs_count_sem2', 'unfounded_abs_count_annual', 'grades_sem1', 'grades_sem2', 'second_examination_grades', 'difference_grades_sem1', 'difference_grades_sem2', 'abs_sem1', 'abs_sem2', 'wants_thesis', 'is_exempted', 'is_coordination_subject' ]
def test_authorize_absence_already_founded(self): self.client.login(username=self.teacher.username, password='******') absence = SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog, is_founded=True) response = self.client.post(self.build_url(absence.id), data={}) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data['message'], "This absence is already authorized.")
def test_delete_user_student_has_data(self): self.client.login(username=self.principal.username, password='******') student1 = UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, school_unit=self.school_unit) SubjectGradeFactory(student=student1) student2 = UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, school_unit=self.school_unit) SubjectAbsenceFactory(student=student2) student3 = UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, school_unit=self.school_unit) ExaminationGradeFactory(student=student3) for student in [student1, student2, student3]: response = self.client.delete(self.build_url(student.id)) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data['message'], "This user cannot be deleted because it's either active or has data.")
def _build_absences(catalog_per_subject, target_date, current_date, founded_absences, unfounded_absences): year = current_date.year month = current_date.month target_year = target_date.year target_month = target_date.month absences = [] # build absences for the current date as well to make sure all those for the target date are considered absences.extend( SubjectAbsenceFactory.build_batch( unfounded_absences, catalog_per_subject=catalog_per_subject, student=catalog_per_subject.student, taken_at=datetime.date(target_year, target_month, 1))) absences.extend( SubjectAbsenceFactory.build_batch( unfounded_absences, catalog_per_subject=catalog_per_subject, student=catalog_per_subject.student, taken_at=datetime.date(year, month, 1))) absences.extend( SubjectAbsenceFactory.build_batch( founded_absences, catalog_per_subject=catalog_per_subject, student=catalog_per_subject.student, is_founded=True, taken_at=datetime.date(target_year, target_month, 1))) absences.extend( SubjectAbsenceFactory.build_batch( founded_absences, catalog_per_subject=catalog_per_subject, student=catalog_per_subject.student, is_founded=True, taken_at=datetime.date(year, month, 1))) return absences
def test_delete_absence_second_semester_success(self, timezone_mock): self.client.login(username=self.teacher.username, password='******') absence = SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog, semester=2, is_founded=True) self.catalog.abs_count_sem2 = 1 self.catalog.abs_count_annual = 2 self.catalog.founded_abs_count_sem2 = 1 self.catalog.founded_abs_count_annual = 1 self.catalog.save() response = self.client.delete(self.build_url(absence.id)) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertCountEqual(response.data.keys(), self.expected_fields) self.assertFalse(SubjectAbsence.objects.filter(id=absence.id).exists()) 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, 0) self.assertEqual(catalog.founded_abs_count_sem2, 0) self.assertEqual(catalog.founded_abs_count_annual, 0) self.assertEqual(catalog.unfounded_abs_count_sem1, 1) self.assertEqual(catalog.unfounded_abs_count_sem2, 0) 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, 1) self.assertEqual(obj.unfounded_abs_avg_sem2, 0) self.assertEqual(obj.unfounded_abs_avg_annual, 1) self.assertEqual(self.teacher.last_change_in_catalog, timezone.now()) self.assertEqual(self.school_unit.last_change_in_catalog, timezone.now())
def test_authorize_absence_success(self, profile_param, timezone_mock): profile = getattr(self, profile_param) self.client.login(username=profile.username, password='******') absence = SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog, semester=2) self.catalog.abs_count_sem2 = 1 self.catalog.abs_count_annual = 2 self.catalog.unfounded_abs_count_sem2 = 1 self.catalog.unfounded_abs_count_annual = 2 self.catalog.save() response = self.client.post(self.build_url(absence.id), data={}) self.assertEqual(response.status_code, status.HTTP_200_OK) self.refresh_objects_from_db([ absence, self.catalog, self.catalog_per_year, self.study_class, self.study_class.academic_program, profile, self.school_unit, self.school_stats ]) self.assertTrue(absence.is_founded) for catalog in [self.catalog, self.catalog_per_year]: self.assertEqual(catalog.abs_count_sem1, 1) self.assertEqual(catalog.abs_count_sem2, 1) self.assertEqual(catalog.abs_count_annual, 2) self.assertEqual(catalog.founded_abs_count_sem1, 0) self.assertEqual(catalog.founded_abs_count_sem2, 1) self.assertEqual(catalog.founded_abs_count_annual, 1) self.assertEqual(catalog.unfounded_abs_count_sem1, 1) self.assertEqual(catalog.unfounded_abs_count_sem2, 0) 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, 1) self.assertEqual(obj.unfounded_abs_avg_sem2, 0) self.assertEqual(obj.unfounded_abs_avg_annual, 1) self.assertEqual(profile.last_change_in_catalog, timezone.now()) self.assertEqual(self.school_unit.last_change_in_catalog, timezone.now())
def test_user_profile_update_role_not_allowed(self): student1 = UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, last_online=timezone.now(), school_unit=self.school_unit) student2 = UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, school_unit=self.school_unit) SubjectGradeFactory(student=student2) student3 = UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, school_unit=self.school_unit) SubjectAbsenceFactory(student=student3) student4 = UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, school_unit=self.school_unit) ExaminationGradeFactory(student=student4) self.client.login(username=self.principal.username, password='******') self.student_data['user_role'] = UserProfile.UserRoles.PARENT for student in [student1, student2, student3, student4]: response = self.client.put(self.build_url(student.id), self.student_data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data['user_role'], ['Cannot change user role.']) teacher = UserProfileFactory(user_role=UserProfile.UserRoles.TEACHER, school_unit=self.school_unit) TeacherClassThroughFactory(teacher=teacher) self.teacher_data['user_role'] = UserProfile.UserRoles.STUDENT response = self.client.put(self.build_url(teacher.id), self.teacher_data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data['user_role'], ['Cannot change user role.'])
def test_get_unfounded_absences_count_for_student(self): self.assertEqual( get_unfounded_absences_count_for_student(self.student.id, self.academic_year, 1), 0) SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog1, academic_year=self.academic_year, semester=1) SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog1, academic_year=self.academic_year, semester=2) SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog1, academic_year=self.academic_year - 1, semester=1) SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog1, academic_year=self.academic_year - 1, semester=2) SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog1, academic_year=self.academic_year, semester=1, is_founded=True) SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog1, academic_year=self.academic_year, semester=2, is_founded=True) self.assertEqual( get_unfounded_absences_count_for_student(self.student.id, self.academic_year, 1), 1) self.assertEqual( get_unfounded_absences_count_for_student(self.student.id, self.academic_year, 2), 1)
def test_own_child_activity_history_grades_and_absences(self): self.client.login(username=self.parent.username, password='******') today = timezone.now().date() yesterday = (timezone.now() - timezone.timedelta(days=1)).replace(tzinfo=utc) two_days_ago = (timezone.now() - timezone.timedelta(days=2)).date() three_days_ago = (timezone.now() - timezone.timedelta(days=3)).date() catalog = StudentCatalogPerSubjectFactory(student=self.student, is_coordination_subject=True) with patch('django.utils.timezone.now', return_value=yesterday) as mocked_method: SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog, is_founded=True, taken_at=yesterday.date()) absence = SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog, is_founded=False, taken_at=yesterday.date()) SubjectGradeFactory(student=self.student, catalog_per_subject=catalog, taken_at=three_days_ago) SubjectGradeFactory(student=self.student, catalog_per_subject=self.catalog, taken_at=two_days_ago, grade_type=SubjectGrade.GradeTypes.THESIS, grade=9) # An absence & grade that were just taken SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog) SubjectGradeFactory(student=self.student, catalog_per_subject=self.catalog) absence.is_founded = True absence.save() response = self.client.get(self.build_url(self.student.id)) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 4) self.assertEqual(response.data[0]['date'], today.strftime('%d-%m-%Y')) self.assertEqual(response.data[0]['subject_name'], self.catalog.subject_name) self.assertEqual(response.data[0]['event_type'], 'ABSENCE_AUTHORIZATION') self.assertEqual( response.data[0]['event'], 'Authorized absence from {}'.format(yesterday.strftime('%d-%m'))) self.assertEqual(response.data[1]['date'], yesterday.strftime('%d-%m-%Y')) self.assertEqual(response.data[1]['subject_name'], self.catalog.subject_name) self.assertEqual(response.data[1]['event_type'], 'NEW_AUTHORIZED_ABSENCE') self.assertEqual(response.data[1]['event'], 'Authorized absence') self.assertEqual(response.data[2]['date'], two_days_ago.strftime('%d-%m-%Y')) self.assertEqual(response.data[2]['subject_name'], self.catalog.subject_name) self.assertEqual(response.data[2]['event_type'], 'NEW_GRADE') self.assertEqual(response.data[2]['event'], 'Thesis grade 9') self.assertEqual(response.data[2]['grade_limit'], 5) self.assertEqual(response.data[2]['grade_value'], 9) self.assertEqual(response.data[3]['date'], three_days_ago.strftime('%d-%m-%Y')) self.assertEqual(response.data[3]['subject_name'], catalog.subject_name) self.assertEqual(response.data[3]['event_type'], 'NEW_GRADE') self.assertEqual(response.data[3]['event'], 'Grade 10') self.assertEqual(response.data[3]['grade_limit'], 6) self.assertEqual(response.data[3]['grade_value'], 10)
def test_own_absences_evolution_success(self, mocked_method): self.client.login(username=self.student.username, password='******') catalog1 = StudentCatalogPerSubjectFactory(student=self.student) for day in [5, 10]: absence = SubjectAbsenceFactory(student=self.student, catalog_per_subject=catalog1, is_founded=True, taken_at=datetime.date( 2020, 6, day)) absence.created = datetime.datetime(2020, 6, day).replace(tzinfo=utc) absence.save() catalog2 = StudentCatalogPerSubjectFactory(student=self.student) for day in [5, 11]: absence = SubjectAbsenceFactory(student=self.student, catalog_per_subject=catalog2, is_founded=False, taken_at=datetime.date( 2020, 6, day)) absence.created = datetime.datetime(2020, 6, day).replace(tzinfo=utc) absence.save() SubjectAbsenceFactory(student=self.student, catalog_per_subject=catalog2, is_founded=True, taken_at=datetime.date(2020, 6, 16)) response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 30) self.assertEqual(response.data[4]['day'], 5) self.assertEqual(response.data[4]['weekday'], 'Vi') self.assertEqual(response.data[4]['total_count'], 2) self.assertEqual(response.data[9]['day'], 10) self.assertEqual(response.data[9]['weekday'], 'Mi') self.assertEqual(response.data[9]['total_count'], 1) self.assertEqual(response.data[10]['day'], 11) self.assertEqual(response.data[10]['weekday'], 'Jo') self.assertEqual(response.data[10]['total_count'], 1) response = self.client.get(self.url, {'by_category': 'true'}) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 30) self.assertEqual(response.data[4]['day'], 5) self.assertEqual(response.data[4]['weekday'], 'Vi') self.assertEqual(response.data[4]['founded_count'], 1) self.assertEqual(response.data[4]['unfounded_count'], 1) self.assertEqual(response.data[9]['day'], 10) self.assertEqual(response.data[9]['weekday'], 'Mi') self.assertEqual(response.data[9]['founded_count'], 1) self.assertEqual(response.data[9]['unfounded_count'], 0) self.assertEqual(response.data[10]['day'], 11) self.assertEqual(response.data[10]['weekday'], 'Jo') self.assertEqual(response.data[10]['founded_count'], 0) self.assertEqual(response.data[10]['unfounded_count'], 1)
def test_own_study_class_catalog_per_subject_success(self): self.client.login(username=self.teacher.username, password='******') catalog1 = StudentCatalogPerSubjectFactory( subject=self.subject, teacher=self.teacher, student=UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, full_name='a'), study_class=self.study_class, academic_year=2020, avg_sem1=1, avg_sem2=1, avg_final=1, abs_count_sem1=1, abs_count_sem2=1, abs_count_annual=1 ) grade1 = SubjectGradeFactory( catalog_per_subject=catalog1, student=catalog1.student, semester=1, grade=10 ) grade2 = SubjectGradeFactory( catalog_per_subject=catalog1, student=catalog1.student, semester=1, grade=9 ) grade3 = SubjectGradeFactory( catalog_per_subject=catalog1, student=catalog1.student, semester=2, grade=3, grade_type=SubjectGrade.GradeTypes.THESIS ) absence1 = SubjectAbsenceFactory( catalog_per_subject=catalog1, student=catalog1.student, semester=1 ) absence2 = SubjectAbsenceFactory( catalog_per_subject=catalog1, student=catalog1.student, semester=1 ) absence3 = SubjectAbsenceFactory( catalog_per_subject=catalog1, student=catalog1.student, semester=2 ) examination_grade1 = ExaminationGradeFactory( catalog_per_subject=catalog1, student=catalog1.student, subject_name=self.subject.name, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE, semester=1 ) examination_grade2 = ExaminationGradeFactory( catalog_per_subject=catalog1, student=catalog1.student, subject_name=self.subject.name, grade_type=ExaminationGrade.GradeTypes.SECOND_EXAMINATION ) catalog2 = StudentCatalogPerSubjectFactory( subject=self.subject, teacher=self.teacher, student=UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT, full_name='b'), study_class=self.study_class, academic_year=2020, avg_sem1=1, avg_sem2=1, avg_final=1, abs_count_sem1=1, abs_count_sem2=1, abs_count_annual=1 ) grade4 = SubjectGradeFactory( catalog_per_subject=catalog2, student=catalog2.student, semester=1, grade=10 ) grade5 = SubjectGradeFactory( catalog_per_subject=catalog2, student=catalog2.student, semester=1, grade=9 ) grade6 = SubjectGradeFactory( catalog_per_subject=catalog2, student=catalog2.student, semester=2, grade=3 ) absence4 = SubjectAbsenceFactory( catalog_per_subject=catalog2, student=catalog2.student, semester=1 ) absence5 = SubjectAbsenceFactory( catalog_per_subject=catalog2, student=catalog2.student, semester=1 ) absence6 = SubjectAbsenceFactory( catalog_per_subject=catalog2, student=catalog2.student, semester=2 ) examination_grade3 = ExaminationGradeFactory( catalog_per_subject=catalog2, student=catalog2.student, subject_name=self.subject.name, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE, semester=2 ) examination_grade4 = ExaminationGradeFactory( catalog_per_subject=catalog2, student=catalog2.student, subject_name=self.subject.name, grade_type=ExaminationGrade.GradeTypes.SECOND_EXAMINATION, semester=1 ) response = self.client.get(self.build_url(self.study_class.id, self.subject.id)) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 2) catalog_expected_fields = [ 'id', 'student', 'avg_sem1', 'avg_sem2', 'avg_annual', 'avg_after_2nd_examination', 'avg_limit', 'abs_count_sem1', 'abs_count_sem2', 'abs_count_annual', 'founded_abs_count_sem1', 'founded_abs_count_sem2', 'founded_abs_count_annual', 'unfounded_abs_count_sem1', 'unfounded_abs_count_sem2', 'unfounded_abs_count_annual', 'grades_sem1', 'grades_sem2', 'abs_sem1', 'abs_sem2', 'second_examination_grades', 'difference_grades_sem1', 'difference_grades_sem2', 'wants_thesis', 'is_exempted', 'third_of_hours_count_sem1', 'third_of_hours_count_sem2', 'third_of_hours_count_annual', 'is_coordination_subject' ] student_expected_fields = ['id', 'full_name', 'labels', 'risk_description'] label_expected_fields = ['id', 'text'] grade_fields = ['id', 'grade', 'taken_at', 'grade_type', 'created'] absence_fields = ['id', 'taken_at', 'is_founded', 'created'] examination_grade_fields = ['id', 'examination_type', 'taken_at', 'grade1', 'grade2', 'created'] for catalog_data in response.data: self.assertCountEqual(catalog_data.keys(), catalog_expected_fields) self.assertCountEqual(catalog_data['student'].keys(), student_expected_fields) for label_data in catalog_data['student']['labels']: self.assertCountEqual(label_data.keys(), label_expected_fields) for grade_data in catalog_data['grades_sem1'] + catalog_data['grades_sem2']: self.assertCountEqual(grade_data.keys(), grade_fields) for absence_data in catalog_data['abs_sem1'] + catalog_data['abs_sem2']: self.assertCountEqual(absence_data.keys(), absence_fields) for examination_data in catalog_data['second_examination_grades'] + catalog_data['difference_grades_sem1'] + catalog_data['difference_grades_sem2']: self.assertCountEqual(examination_data.keys(), examination_grade_fields) self.assertEqual(catalog_data['avg_limit'], 5) self.assertEqual(catalog_data['third_of_hours_count_sem1'], 15) self.assertEqual(catalog_data['third_of_hours_count_sem2'], 15) self.assertEqual(catalog_data['third_of_hours_count_annual'], 30) self.assertCountEqual([grade['id'] for grade in response.data[0]['grades_sem1']], [grade1.id, grade2.id]) self.assertCountEqual([grade['id'] for grade in response.data[0]['grades_sem2']], [grade3.id]) self.assertCountEqual([grade['id'] for grade in response.data[1]['grades_sem1']], [grade4.id, grade5.id]) self.assertCountEqual([grade['id'] for grade in response.data[1]['grades_sem2']], [grade6.id]) self.assertCountEqual([absence['id'] for absence in response.data[0]['abs_sem1']], [absence1.id, absence2.id]) self.assertCountEqual([absence['id'] for absence in response.data[0]['abs_sem2']], [absence3.id]) self.assertCountEqual([absence['id'] for absence in response.data[1]['abs_sem1']], [absence4.id, absence5.id]) self.assertCountEqual([absence['id'] for absence in response.data[1]['abs_sem2']], [absence6.id]) self.assertCountEqual([grade['id'] for grade in response.data[0]['difference_grades_sem1']], [examination_grade1.id]) self.assertCountEqual(response.data[0]['difference_grades_sem2'], []) self.assertCountEqual([grade['id'] for grade in response.data[0]['second_examination_grades']], [examination_grade2.id]) self.assertCountEqual(response.data[1]['difference_grades_sem1'], []) self.assertCountEqual([grade['id'] for grade in response.data[1]['difference_grades_sem2']], [examination_grade3.id]) self.assertCountEqual([grade['id'] for grade in response.data[1]['second_examination_grades']], [examination_grade4.id])
def test_own_study_class_pupil_detail_success(self): self.client.login(username=self.teacher.username, password='******') parent = UserProfileFactory(user_role=UserProfile.UserRoles.PARENT, school_unit=self.school_unit) self.student.parents.add(parent) label = LabelFactory(user_role=UserProfile.UserRoles.STUDENT) self.student.labels.add(label) coordination_subject = SubjectFactory(name='Dirigentie', is_coordination=True) subject1 = SubjectFactory(name='Subject') subject2 = SubjectFactory(name='Another Subject') subject3 = SubjectFactory(name='Optional Subject') teacher2 = UserProfileFactory(user_role=UserProfile.UserRoles.TEACHER, school_unit=self.school_unit) TeacherClassThroughFactory(study_class=self.study_class, teacher=self.teacher, subject=coordination_subject, is_class_master=True) TeacherClassThroughFactory(study_class=self.study_class, teacher=self.teacher, subject=subject1, is_class_master=True) TeacherClassThroughFactory(study_class=self.study_class, teacher=teacher2, subject=subject2) TeacherClassThroughFactory(study_class=self.study_class, teacher=teacher2, subject=subject3) catalog1 = StudentCatalogPerSubjectFactory( student=self.student, teacher=self.teacher, study_class=self.study_class, subject=coordination_subject) catalog2 = StudentCatalogPerSubjectFactory( student=self.student, teacher=self.teacher, study_class=self.study_class, subject=subject1) catalog3 = StudentCatalogPerSubjectFactory( student=self.student, teacher=teacher2, study_class=self.study_class, subject=subject2) StudentCatalogPerSubjectFactory(student=self.student, teacher=teacher2, study_class=self.study_class, subject=subject3, is_enrolled=False) for subject in [subject1, subject2]: ProgramSubjectThroughFactory( academic_program=self.study_class.academic_program, class_grade=self.study_class.class_grade, subject=subject, weekly_hours_count=1) yesterday = timezone.now().date() - timezone.timedelta(days=1) grade1 = SubjectGradeFactory(student=self.student, catalog_per_subject=catalog2) grade2 = SubjectGradeFactory(student=self.student, catalog_per_subject=catalog2, taken_at=yesterday) grade3 = SubjectGradeFactory(student=self.student, catalog_per_subject=catalog2, semester=2, taken_at=yesterday) grade4 = SubjectGradeFactory(student=self.student, catalog_per_subject=catalog2, semester=2) exam_grade1 = ExaminationGradeFactory(student=self.student, catalog_per_subject=catalog2) exam_grade2 = ExaminationGradeFactory( student=self.student, catalog_per_subject=catalog2, examination_type=ExaminationGrade.ExaminationTypes.ORAL) exam_grade3 = ExaminationGradeFactory( student=self.student, catalog_per_subject=catalog2, taken_at=yesterday, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE, semester=1) exam_grade4 = ExaminationGradeFactory( student=self.student, catalog_per_subject=catalog2, examination_type=ExaminationGrade.ExaminationTypes.ORAL, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE, semester=1) exam_grade5 = ExaminationGradeFactory( student=self.student, catalog_per_subject=catalog2, semester=2, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE) exam_grade6 = ExaminationGradeFactory( student=self.student, catalog_per_subject=catalog2, taken_at=yesterday, semester=2, examination_type=ExaminationGrade.ExaminationTypes.ORAL, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE) abs1 = SubjectAbsenceFactory(student=self.student, catalog_per_subject=catalog2) abs2 = SubjectAbsenceFactory(student=self.student, catalog_per_subject=catalog2, taken_at=yesterday) abs3 = SubjectAbsenceFactory(student=self.student, catalog_per_subject=catalog2, semester=2, taken_at=yesterday) abs4 = SubjectAbsenceFactory(student=self.student, catalog_per_subject=catalog2, semester=2) response = self.client.get( self.build_url(self.study_class.id, self.student.id)) self.assertEqual(response.status_code, status.HTTP_200_OK) expected_fields = [ 'id', 'full_name', 'parents', 'labels', 'risk_description', 'study_class', 'catalogs_per_subjects' ] catalog_expected_fields = [ 'id', 'subject_name', 'teacher', 'avg_sem1', 'avg_sem2', 'avg_annual', 'avg_after_2nd_examination', 'avg_limit', 'grades_sem1', 'grades_sem2', 'second_examination_grades', 'difference_grades_sem1', 'difference_grades_sem2', 'abs_count_sem1', 'abs_count_sem2', 'abs_count_annual', 'founded_abs_count_sem1', 'founded_abs_count_sem2', 'founded_abs_count_annual', 'unfounded_abs_count_sem1', 'unfounded_abs_count_sem2', 'unfounded_abs_count_annual', 'third_of_hours_count_sem1', 'third_of_hours_count_sem2', 'third_of_hours_count_annual', 'abs_sem1', 'abs_sem2', 'wants_thesis', 'is_exempted', 'is_coordination_subject' ] profile_expected_fields = ['id', 'full_name'] label_expected_fields = ['id', 'text'] study_class_expected_fields = ['id', 'class_grade', 'class_letter'] grade_expected_fields = [ 'id', 'grade', 'taken_at', 'grade_type', 'created' ] absence_expected_fields = ['id', 'taken_at', 'is_founded', 'created'] exam_grade_expected_fields = [ 'id', 'examination_type', 'grade1', 'grade2', 'taken_at', 'created' ] self.assertCountEqual(response.data.keys(), expected_fields) self.assertEqual(len(response.data['parents']), 1) self.assertCountEqual(response.data['parents'][0].keys(), profile_expected_fields) self.assertEqual(len(response.data['labels']), 1) self.assertCountEqual(response.data['labels'][0].keys(), label_expected_fields) self.assertCountEqual(response.data['study_class'].keys(), study_class_expected_fields) catalogs_per_subjects = response.data['catalogs_per_subjects'] self.assertEqual(len(catalogs_per_subjects), 3) for catalog_data in catalogs_per_subjects: self.assertCountEqual(catalog_data.keys(), catalog_expected_fields) self.assertCountEqual(catalog_data['teacher'].keys(), profile_expected_fields) self.assertEqual(catalog_data['avg_limit'], 6 if catalog_data['id'] == catalog1.id else 5) self.assertEqual(catalog_data['third_of_hours_count_sem1'], 5) self.assertEqual(catalog_data['third_of_hours_count_sem2'], 5) self.assertEqual(catalog_data['third_of_hours_count_annual'], 10) self.assertEqual(catalogs_per_subjects[0]['id'], catalog1.id) self.assertEqual(catalogs_per_subjects[0]['teacher']['id'], self.teacher.id) self.assertEqual(catalogs_per_subjects[0]['subject_name'], coordination_subject.name) self.assertEqual(catalogs_per_subjects[1]['id'], catalog3.id) self.assertEqual(catalogs_per_subjects[1]['teacher']['id'], teacher2.id) self.assertEqual(catalogs_per_subjects[1]['subject_name'], subject2.name) self.assertEqual(catalogs_per_subjects[2]['id'], catalog2.id) self.assertEqual(catalogs_per_subjects[2]['teacher']['id'], self.teacher.id) self.assertEqual(catalogs_per_subjects[2]['subject_name'], subject1.name) for grade_data in catalogs_per_subjects[2][ 'grades_sem1'] + catalogs_per_subjects[2]['grades_sem2']: self.assertCountEqual(grade_data.keys(), grade_expected_fields) for abs_data in catalogs_per_subjects[2][ 'abs_sem1'] + catalogs_per_subjects[2]['abs_sem2']: self.assertCountEqual(abs_data.keys(), absence_expected_fields) for exam_grade_data in catalogs_per_subjects[2]['second_examination_grades'] + \ catalogs_per_subjects[2]['difference_grades_sem1'] + catalogs_per_subjects[2]['difference_grades_sem2']: self.assertCountEqual(exam_grade_data.keys(), exam_grade_expected_fields) self.assertEqual(catalogs_per_subjects[2]['grades_sem1'][0]['id'], grade1.id) self.assertEqual(catalogs_per_subjects[2]['grades_sem1'][1]['id'], grade2.id) self.assertEqual(catalogs_per_subjects[2]['grades_sem2'][0]['id'], grade4.id) self.assertEqual(catalogs_per_subjects[2]['grades_sem2'][1]['id'], grade3.id) self.assertEqual(catalogs_per_subjects[2]['abs_sem1'][0]['id'], abs1.id) self.assertEqual(catalogs_per_subjects[2]['abs_sem1'][1]['id'], abs2.id) self.assertEqual(catalogs_per_subjects[2]['abs_sem2'][0]['id'], abs4.id) self.assertEqual(catalogs_per_subjects[2]['abs_sem2'][1]['id'], abs3.id) self.assertEqual( catalogs_per_subjects[2]['second_examination_grades'][0]['id'], exam_grade2.id) self.assertEqual( catalogs_per_subjects[2]['second_examination_grades'][1]['id'], exam_grade1.id) self.assertEqual( catalogs_per_subjects[2]['difference_grades_sem1'][0]['id'], exam_grade4.id) self.assertEqual( catalogs_per_subjects[2]['difference_grades_sem1'][1]['id'], exam_grade3.id) self.assertEqual( catalogs_per_subjects[2]['difference_grades_sem2'][0]['id'], exam_grade5.id) self.assertEqual( catalogs_per_subjects[2]['difference_grades_sem2'][1]['id'], exam_grade6.id)
def test_catalog_export_success(self): self.client.login(username=self.teacher.username, password='******') expected_fields = [ 'Nume', 'Clasă', 'Etichete', 'Note sem. I', 'Teză sem. I', 'Medie sem. I', 'Note sem. II', 'Teză sem. II', 'Medie sem. II', 'Medie anuală', 'Absențe motivate sem. I', 'Absențe nemotivate sem. I', 'Absențe motivate sem. II', 'Absențe nemotivate sem. II', 'Observații', 'Teste inițiale / finale', 'Teză', 'Simulări', 'Scutit', 'Înregistrat opțional', 'Corigență Oral Prof. I', 'Corigență Oral Prof. II', 'Corigență Scris Prof. II', 'Corigență Scris Prof. I', 'Diferență sem. I Oral Prof. I', 'Diferență sem. I Oral Prof. II', 'Diferență sem. I Scris Prof. I', 'Diferență sem. I Scris Prof. II', 'Diferență sem. II Oral Prof. I', 'Diferență sem. II Oral Prof. II', 'Diferență sem. II Scris Prof. I', 'Diferență sem. II Scris Prof. II', 'Diferență anuală Oral Prof. I', 'Diferență anuală Oral Prof. II', 'Diferență anuală Scris Prof. I', 'Diferență anuală Scris Prof. II' ] boolean_fields = ['Teste inițiale / finale', 'Teză', 'Simulări', 'Scutit', 'Înregistrat opțional'] response = self.client.get(self.build_url(self.study_class.id, self.subject.id)) self.assertEqual(response.status_code, status.HTTP_200_OK) row_nr = 0 for index, row in enumerate(self.get_csv_rows_from_response(response)): self.assertCountEqual(row.keys(), expected_fields) for key, value in row.items(): self.assertNotEqual(value, '') if key not in ['Nume', 'Clasă', 'Etichete', *boolean_fields]: self.assertEqual(value, '-') row_nr += 1 self.assertEqual(row_nr, 1) catalog = StudentCatalogPerSubjectFactory( study_class=self.study_class, teacher=self.teacher, subject=self.subject, student__full_name='b', remarks='very good', avg_sem1=2, avg_sem2=2, avg_final=2, abs_count_sem1=2, abs_count_sem2=2, abs_count_annual=2, ) catalog.student.labels.add(LabelFactory(user_role=UserProfile.UserRoles.STUDENT)) SubjectGradeFactory(student=catalog.student, catalog_per_subject=catalog, semester=1, grade=10, grade_type=SubjectGrade.GradeTypes.REGULAR) SubjectGradeFactory(student=catalog.student, catalog_per_subject=catalog, semester=1, grade=9, grade_type=SubjectGrade.GradeTypes.REGULAR) SubjectGradeFactory(student=catalog.student, catalog_per_subject=catalog, semester=2, grade=10, grade_type=SubjectGrade.GradeTypes.REGULAR) SubjectGradeFactory(student=catalog.student, catalog_per_subject=catalog, semester=2, grade=9, grade_type=SubjectGrade.GradeTypes.REGULAR) SubjectGradeFactory(student=catalog.student, catalog_per_subject=catalog, semester=1, grade=10, grade_type=SubjectGrade.GradeTypes.THESIS) SubjectGradeFactory(student=catalog.student, catalog_per_subject=catalog, semester=2, grade=7, grade_type=SubjectGrade.GradeTypes.THESIS) SubjectAbsenceFactory(student=catalog.student, catalog_per_subject=catalog, is_founded=True, taken_at=datetime.date(2019, 12, 12), semester=1) SubjectAbsenceFactory(student=catalog.student, catalog_per_subject=catalog, is_founded=True, taken_at=datetime.date(2019, 12, 13), semester=1) SubjectAbsenceFactory(student=catalog.student, catalog_per_subject=catalog, is_founded=False, taken_at=datetime.date(2019, 12, 12), semester=1) SubjectAbsenceFactory(student=catalog.student, catalog_per_subject=catalog, is_founded=False, taken_at=datetime.date(2019, 12, 13), semester=1) SubjectAbsenceFactory(student=catalog.student, catalog_per_subject=catalog, is_founded=True, taken_at=datetime.date(2020, 4, 2), semester=2) SubjectAbsenceFactory(student=catalog.student, catalog_per_subject=catalog, is_founded=True, taken_at=datetime.date(2020, 4, 3), semester=2) SubjectAbsenceFactory(student=catalog.student, catalog_per_subject=catalog, is_founded=False, taken_at=datetime.date(2020, 4, 2), semester=2) SubjectAbsenceFactory(student=catalog.student, catalog_per_subject=catalog, is_founded=False, taken_at=datetime.date(2020, 4, 3), semester=2) ExaminationGradeFactory( student=catalog.student, catalog_per_subject=catalog, taken_at=datetime.date(2020, 4, 3), grade1=5, grade2=6, grade_type=ExaminationGrade.GradeTypes.SECOND_EXAMINATION, examination_type=ExaminationGrade.ExaminationTypes.WRITTEN ) ExaminationGradeFactory( student=catalog.student, catalog_per_subject=catalog, taken_at=datetime.date(2020, 4, 3), grade1=7, grade2=8, grade_type=ExaminationGrade.GradeTypes.SECOND_EXAMINATION, examination_type=ExaminationGrade.ExaminationTypes.ORAL ) ExaminationGradeFactory( student=catalog.student, catalog_per_subject=catalog, taken_at=datetime.date(2019, 12, 12), grade1=7, grade2=8, semester=1, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE, examination_type=ExaminationGrade.ExaminationTypes.WRITTEN ) ExaminationGradeFactory( student=catalog.student, catalog_per_subject=catalog, taken_at=datetime.date(2019, 12, 12), grade1=7, grade2=8, semester=2, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE, examination_type=ExaminationGrade.ExaminationTypes.WRITTEN ) ExaminationGradeFactory( student=catalog.student, catalog_per_subject=catalog, taken_at=datetime.date(2020, 4, 3), grade1=7, grade2=8, semester=1, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE, examination_type=ExaminationGrade.ExaminationTypes.ORAL ) ExaminationGradeFactory( student=catalog.student, catalog_per_subject=catalog, taken_at=datetime.date(2020, 4, 3), grade1=7, grade2=8, semester=2, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE, examination_type=ExaminationGrade.ExaminationTypes.ORAL ) ExaminationGradeFactory( student=catalog.student, catalog_per_subject=catalog, taken_at=datetime.date(2019, 12, 12), grade1=7, grade2=8, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE, examination_type=ExaminationGrade.ExaminationTypes.WRITTEN ) ExaminationGradeFactory( student=catalog.student, catalog_per_subject=catalog, taken_at=datetime.date(2020, 4, 3), grade1=7, grade2=8, grade_type=ExaminationGrade.GradeTypes.DIFFERENCE, examination_type=ExaminationGrade.ExaminationTypes.ORAL ) response = self.client.get(self.build_url(self.study_class.id, self.subject.id)) self.assertEqual(response.status_code, status.HTTP_200_OK) row_nr = 0 for index, row in enumerate(self.get_csv_rows_from_response(response)): row_nr += 1 self.assertCountEqual(row.keys(), expected_fields) if row_nr == 1: self.assertEqual(row['Nume'], 'a') for key, value in row.items(): self.assertNotEqual(value, '') if row_nr == 2: self.assertEqual(row['Nume'], 'b') for field in ['Note sem. I', 'Note sem. II', 'Absențe motivate sem. I', 'Absențe nemotivate sem. I', 'Absențe motivate sem. II', 'Absențe nemotivate sem. II']: self.assertEqual(len(row[field].split(';')), 2) for field in [ 'Diferență sem. I Oral Prof. I', 'Diferență sem. I Oral Prof. II', 'Diferență sem. I Scris Prof. I', 'Diferență sem. I Scris Prof. II', 'Diferență sem. II Oral Prof. I', 'Diferență sem. II Oral Prof. II', 'Diferență sem. II Scris Prof. I', 'Diferență sem. II Scris Prof. II', 'Diferență anuală Oral Prof. I', 'Diferență anuală Oral Prof. II', 'Diferență anuală Scris Prof. I', 'Diferență anuală Scris Prof. II' ]: self.assertEqual(len(row[field].split(';')), 1) for field in ['Teză', 'Scutit', 'Simulări', 'Scutit', 'Teste inițiale / finale']: self.assertEqual(row[field], 'Nu') self.assertEqual(row['Înregistrat opțional'], 'Da') self.assertEqual(len([value for value in row.values() if value != '-']), len(row.values())) self.assertEqual(row_nr, 2)
def test_own_child_absences_evolution_month_filter(self, mocked_method): self.client.login(username=self.parent.username, password='******') catalog1 = StudentCatalogPerSubjectFactory(student=self.student) for day in [5, 11]: absence = SubjectAbsenceFactory(student=self.student, catalog_per_subject=catalog1, is_founded=True, taken_at=datetime.date( 2020, 5, day)) absence.created = datetime.datetime(2020, 5, day).replace(tzinfo=utc) absence.save() catalog2 = StudentCatalogPerSubjectFactory(student=self.student) for day in [5, 13]: absence = SubjectAbsenceFactory(student=self.student, catalog_per_subject=catalog2, is_founded=False, taken_at=datetime.date( 2020, 5, day)) absence.created = datetime.datetime(2020, 5, day).replace(tzinfo=utc) absence.save() response = self.client.get(self.build_url(self.student.id), {'month': 5}) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 31) self.assertEqual(response.data[4]['day'], 5) self.assertEqual(response.data[4]['weekday'], 'Ma') self.assertEqual(response.data[4]['total_count'], 2) self.assertEqual(response.data[10]['day'], 11) self.assertEqual(response.data[10]['weekday'], 'Lu') self.assertEqual(response.data[10]['total_count'], 1) self.assertEqual(response.data[12]['day'], 13) self.assertEqual(response.data[12]['weekday'], 'Mi') self.assertEqual(response.data[12]['total_count'], 1) response = self.client.get(self.build_url(self.student.id), { 'month': 5, 'by_category': 'true' }) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 31) self.assertEqual(response.data[4]['day'], 5) self.assertEqual(response.data[4]['weekday'], 'Ma') self.assertEqual(response.data[4]['founded_count'], 1) self.assertEqual(response.data[4]['unfounded_count'], 1) self.assertEqual(response.data[10]['day'], 11) self.assertEqual(response.data[10]['weekday'], 'Lu') self.assertEqual(response.data[10]['founded_count'], 1) self.assertEqual(response.data[10]['unfounded_count'], 0) self.assertEqual(response.data[12]['day'], 13) self.assertEqual(response.data[12]['weekday'], 'Mi') self.assertEqual(response.data[12]['founded_count'], 0) self.assertEqual(response.data[12]['unfounded_count'], 1)
def test_send_alerts(self, send_sms_mock, send_email_mock, timezone_mock): # add one more student from a different school school2 = RegisteredSchoolUnitFactory() study_class2 = StudyClassFactory(school_unit=school2) student2 = UserProfileFactory(school_unit=school2, user_role=UserProfile.UserRoles.STUDENT, student_in_class=study_class2, full_name="Marinescu I. Ioan") catalog3 = StudentCatalogPerSubjectFactory(student=student2, study_class=study_class2, subject=self.subject1) # add 1 unfounded absence for 1st student SubjectAbsenceFactory(student=self.student, catalog_per_subject=self.catalog1, semester=2) # add grades for both of them SubjectGradeFactory(student=self.student, catalog_per_subject=self.catalog1, taken_at=datetime.date(2020, 3, 2), grade=6) SubjectGradeFactory(student=self.student, catalog_per_subject=self.catalog1, taken_at=datetime.date(2020, 3, 4), grade=7) SubjectGradeFactory(student=self.student, catalog_per_subject=self.catalog2, taken_at=datetime.date(2020, 3, 5), grade=5) SubjectGradeFactory(student=student2, catalog_per_subject=catalog3, taken_at=timezone.datetime(2020, 3, 3), grade=10) # add 2 parents for each, one allowing emails, one allowing sms parent1 = UserProfileFactory(school_unit=self.school, user_role=UserProfile.UserRoles.PARENT) parent2 = UserProfileFactory(school_unit=self.school, user_role=UserProfile.UserRoles.PARENT, email_notifications_enabled=False, sms_notifications_enabled=True) parent3 = UserProfileFactory(school_unit=school2, user_role=UserProfile.UserRoles.PARENT) parent4 = UserProfileFactory(school_unit=school2, user_role=UserProfile.UserRoles.PARENT, email_notifications_enabled=False, sms_notifications_enabled=True) self.student.parents.add(parent1, parent2) student2.parents.add(parent3, parent4) # call tested function send_alerts_for_school_situation() # check mocked calls send_email_calls = [ call("Marinescu I. Ioan", "2-8.3", "Limba Romana 10", 0, school2.name, [parent3]), call("Pop Ionut", "2-8.3", "Matematica 5, Limba Romana 7 ; 6", 1, self.school.name, [parent1]) ] send_email_mock.assert_has_calls(send_email_calls, any_order=True) send_sms_calls = [ call("MII", "2-8.3", "LRO 10", 0, [parent4]), call("PI", "2-8.3", "MAT 5, LRO 7 ; 6", 1, [parent2]) ] send_sms_mock.assert_has_calls(send_sms_calls, any_order=True)