def test_user_profile_update_labels_success(self, send_notification_mock):
        self.client.login(username=self.principal.username, password='******')

        profile = UserProfile.objects.filter(user_role=UserProfile.UserRoles.STUDENT).last()
        url = self.build_url(profile.id)

        # Create a few labels
        label1 = LabelFactory(user_role=UserProfile.UserRoles.STUDENT, text=EXPELLED_LABEL)
        label2 = LabelFactory(user_role=UserProfile.UserRoles.STUDENT, text=HELD_BACK_LABEL)

        self.student_data['labels'] = [label1.id, label2.id]
        response = self.client.put(url, self.student_data)

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        profile.refresh_from_db()
        self.assertCountEqual(profile.labels.values_list('id', flat=True), [label1.id, label2.id])

        # Remove one of them
        self.student_data['labels'] = [label1.id]
        response = self.client.put(url, self.student_data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        profile.refresh_from_db()
        self.assertCountEqual(profile.labels.values_list('id', flat=True), [label1.id])

        self.assertEqual(send_notification_mock.call_count, 2)
        calls = [call(EXPELLED_TITLE.format(profile.full_name),
                      EXPELLED_BODY.format(profile.full_name),
                      [self.principal.id], False),
                 call(HELD_BACK_TITLE.format(profile.full_name),
                      HELD_BACK_BODY.format(profile.full_name),
                      [self.principal.id], False)]
        send_notification_mock.assert_has_calls(calls, any_order=True)
    def setUpTestData(cls):
        Label.objects.all().delete()
        for role in UserProfile.UserRoles.values:
            LabelFactory(user_role=role)
            LabelFactory(user_role=role)

        cls.school_unit = RegisteredSchoolUnitFactory()
        cls.url = reverse('users:label-list')
        cls.expected_fields = ['id', 'text']
    def test_teacher_detail(self, profile_param):
        self.client.login(username=getattr(self, profile_param).username, password='******')

        profile = UserProfileFactory(user_role=UserProfile.UserRoles.TEACHER, school_unit=self.school_unit)
        profile.labels.add(LabelFactory(user_role=UserProfile.UserRoles.TEACHER))
        profile.taught_subjects.add(self.subject)

        study_class1 = StudyClassFactory(school_unit=self.school_unit, class_master=profile, class_grade='IX', class_grade_arabic=9)
        teacher_class_through1 = TeacherClassThroughFactory(study_class=study_class1, teacher=profile, is_class_master=True,
                                                            subject=SubjectFactory(name='A subject'))
        teacher_class_through2 = TeacherClassThroughFactory(study_class=study_class1, teacher=profile, is_class_master=True,
                                                            subject=SubjectFactory(name='Dirigentie', is_coordination=True))
        study_class2 = StudyClassFactory(school_unit=self.school_unit)
        teacher_class_through3 = TeacherClassThroughFactory(study_class=study_class2, teacher=profile)
        study_class3 = StudyClassFactory(school_unit=self.school_unit, academic_year=2019)
        TeacherClassThroughFactory(study_class=study_class3, teacher=profile)

        response = self.client.get(self.build_url(profile.id))
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        expected_fields = ['id', 'full_name', 'user_role', 'email', 'phone_number', 'use_phone_as_username',
                           'is_active', 'last_online', 'labels', 'taught_subjects', 'assigned_study_classes']
        self.assertCountEqual(response.data.keys(), expected_fields)
        self.assertCountEqual(response.data['labels'][0].keys(), ['id', 'text'])
        self.assertCountEqual(response.data['taught_subjects'][0].keys(), ['id', 'name'])
        self.assertEqual(len(response.data['assigned_study_classes']), 3)
        self.assertCountEqual(response.data['assigned_study_classes'][0].keys(), ['id', 'study_class_id', 'class_grade', 'class_letter',
                                                                                  'subject_id', 'subject_name', 'is_optional_subject'])
        self.assertEqual(response.data['assigned_study_classes'][0]['id'], teacher_class_through3.id)
        self.assertEqual(response.data['assigned_study_classes'][1]['id'], teacher_class_through1.id)
        self.assertEqual(response.data['assigned_study_classes'][2]['id'], teacher_class_through2.id)
示例#4
0
    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)
示例#5
0
 def setUpTestData(cls):
     cls.school = RegisteredSchoolUnitFactory()
     cls.teacher = UserProfileFactory(
         user_role=UserProfile.UserRoles.TEACHER, school_unit=cls.school)
     cls.study_class = StudyClassFactory(school_unit=cls.school,
                                         class_grade='IX',
                                         class_grade_arabic=9,
                                         class_letter='A')
     cls.student = UserProfileFactory(
         user_role=UserProfile.UserRoles.STUDENT,
         school_unit=cls.school,
         student_in_class=cls.study_class)
     cls.subject = SubjectFactory()
     cls.teacher_class_through = TeacherClassThroughFactory(
         study_class=cls.study_class,
         teacher=cls.teacher,
         subject=cls.subject)
     cls.current_calendar = AcademicYearCalendarFactory()
     cls.label = LabelFactory(user_role=UserProfile.UserRoles.STUDENT,
                              text='good')
     cls.label2 = LabelFactory(user_role=UserProfile.UserRoles.STUDENT,
                               text='v good')
     cls.subject_through = ProgramSubjectThroughFactory(
         subject=cls.subject,
         class_grade='IX',
         class_grade_arabic=9,
         is_mandatory=True,
         generic_academic_program=cls.study_class.academic_program.
         generic_academic_program,
         weekly_hours_count=1,
     )
     cls.differences_event = SchoolEventFactory(
         event_type=SchoolEvent.EventTypes.DIFERENTE,
         semester=cls.current_calendar.first_semester,
         academic_year_calendar=cls.current_calendar,
         starts_at=datetime.date(2019, 12, 21),
         ends_at=datetime.date(2019, 12, 23))
     cls.second_examination_event = SchoolEventFactory(
         event_type=SchoolEvent.EventTypes.CORIGENTE,
         academic_year_calendar=cls.current_calendar,
         starts_at=datetime.date(2020, 5, 4),
         ends_at=datetime.date(2020, 5, 7))
     cls.catalog_per_year = StudentCatalogPerYearFactory(
         study_class=cls.study_class, student=cls.student)
     cls.file_name = 'file.csv'
    def test_parent_detail(self, profile_param):
        self.client.login(username=getattr(self, profile_param).username, password='******')
        self.parent.labels.add(LabelFactory(user_role=UserProfile.UserRoles.PARENT))

        response = self.client.get(self.build_url(self.parent.id))
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        expected_fields = ['id', 'full_name', 'user_role', 'email', 'phone_number',
                           'use_phone_as_username', 'is_active', 'last_online', 'labels', 'address']
        self.assertCountEqual(response.data.keys(), expected_fields)
        self.assertCountEqual(response.data['labels'][0].keys(), ['id', 'text'])
示例#7
0
    def test_catalog_import_label_for_wrong_user_role(self):
        self.client.login(username=self.teacher.username, password='******')
        LabelFactory(text='other_label',
                     user_role=UserProfile.UserRoles.PARENT)
        self.data['Etichete'] = 'other label'

        file = self.create_file(self.file_name)
        self.write_data(file, self.data)

        response = self.get_response(
            self.build_url(self.study_class.id, self.subject.id), file)
        self.assertError(
            response, 'Etichete',
            'Labels must exist, be unique, and be for the student user role.')
    def test_student_detail(self, profile_param):
        self.client.login(username=getattr(self, profile_param).username, password='******')
        self.student.labels.add(LabelFactory(user_role=UserProfile.UserRoles.STUDENT))
        self.student.parents.add(UserProfileFactory(user_role=UserProfile.UserRoles.PARENT))

        response = self.client.get(self.build_url(self.student.id))
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        expected_fields = ['id', 'full_name', 'user_role', 'email', 'phone_number',
                           'use_phone_as_username', 'is_active', 'last_online', 'labels', 'risk_description',
                           'student_in_class', 'address', 'personal_id_number', 'birth_date',
                           'parents', 'educator_full_name', 'educator_email', 'educator_phone_number']
        self.assertCountEqual(response.data.keys(), expected_fields)
        self.assertCountEqual(response.data['labels'][0].keys(), ['id', 'text'])
        self.assertCountEqual(response.data['parents'][0].keys(), ['id', 'full_name', 'phone_number', 'email', 'address'])
        self.assertCountEqual(response.data['student_in_class'].keys(), ['id', 'class_grade', 'class_letter'])
    def test_student_detail_include_risk_alerts(self, profile_param):
        self.client.login(username=getattr(self, profile_param).username, password='******')
        self.student.labels.add(LabelFactory(user_role=UserProfile.UserRoles.STUDENT))
        self.student.parents.add(self.parent)

        notification1 = NotificationFactory()
        target_user_through1 = TargetUserThroughFactory(notification=notification1, user_profile=self.student, sent_at_email='*****@*****.**')
        notification2 = NotificationFactory(receiver_type=Notification.ReceiverTypes.ONE_PARENT,
                                            target_users_role=UserProfile.UserRoles.PARENT, send_sms=True)
        target_user_through2 = TargetUserThroughFactory(notification=notification2, user_profile=self.parent, sent_at_phone_number='0712345678')
        target_user_through2.children.add(self.student)

        response = self.client.get(self.build_url(self.student.id), {'include_risk_alerts': 'true'})
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        expected_fields = ['id', 'full_name', 'user_role', 'email', 'phone_number',
                           'use_phone_as_username', 'is_active', 'last_online', 'labels', 'risk_description',
                           'student_in_class', 'address', 'personal_id_number', 'birth_date',
                           'parents', 'educator_full_name', 'educator_email', 'educator_phone_number', 'risk_alerts']
        self.assertCountEqual(response.data.keys(), expected_fields)
        self.assertCountEqual(response.data['labels'][0].keys(), ['id', 'text'])
        self.assertCountEqual(response.data['parents'][0].keys(), ['id', 'full_name', 'phone_number', 'email', 'address'])
        self.assertCountEqual(response.data['student_in_class'].keys(), ['id', 'class_grade', 'class_letter'])

        risk_alerts = response.data['risk_alerts']
        self.assertEqual(risk_alerts['dates'], {timezone.now().date()})
        self.assertEqual(risk_alerts['alerted_users'][0], {
            'id': self.student.id,
            'user_role': UserProfile.UserRoles.STUDENT,
            'full_name': self.student.full_name,
            'email': target_user_through1.sent_at_email,
            'phone_number': None
        })
        self.assertEqual(risk_alerts['alerted_users'][1], {
            'id': self.parent.id,
            'user_role': UserProfile.UserRoles.PARENT,
            'full_name': self.parent.full_name,
            'email': None,
            'phone_number': target_user_through2.sent_at_phone_number
        })
    def test_user_profile_update_label_validations(self, user_role, data_dict):
        if user_role == UserProfile.UserRoles.PRINCIPAL:
            self.client.login(username=self.admin.username, password='******')
        else:
            self.client.login(username=self.principal.username, password='******')

        url = self.build_url(UserProfile.objects.filter(user_role=user_role).first().id)

        # Label doesn't exist
        data_dict = getattr(self, data_dict)
        data_dict['user_role'] = user_role
        data_dict['labels'] = [0]
        response = self.client.put(url, data_dict)
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertEqual(response.data, {'labels': ['Invalid pk "0" - object does not exist.']})

        # Label with the wrong user_role
        label = LabelFactory(user_role=UserProfile.UserRoles.PARENT if user_role != UserProfile.UserRoles.PARENT else UserProfile.UserRoles.STUDENT)
        data_dict['labels'] = [label.id, ]

        response = self.client.put(url, data_dict)
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertEqual(response.data, {'labels': ['Labels do not correspond to the created user role.']})
示例#11
0
    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_pupils_statistics_school_employee_success(self, profile_param,
                                                       results_count):
        self.client.login(username=getattr(self, profile_param).username,
                          password='******')
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], results_count)

        catalog_expected_fields = [
            'id', 'student', 'avg_sem1', 'avg_sem2', 'avg_final',
            'second_examinations_count', 'unfounded_abs_count_sem1',
            'unfounded_abs_count_sem2', 'unfounded_abs_count_annual',
            'behavior_grade_sem1', 'behavior_grade_sem2',
            'behavior_grade_annual', 'behavior_grade_limit', 'labels',
            'risk_description', 'student_in_class', 'academic_program_name'
        ]
        student_expected_fields = ['id', 'full_name']
        label_expected_fields = ['id', 'text']
        study_class_expected_fields = ['id', 'class_grade', 'class_letter']
        for catalog_data in response.data['results']:
            self.assertCountEqual(catalog_data.keys(), catalog_expected_fields)
            self.assertCountEqual(catalog_data['student'].keys(),
                                  student_expected_fields)
            self.assertCountEqual(catalog_data['student_in_class'].keys(),
                                  study_class_expected_fields)
            for label_data in catalog_data['labels']:
                self.assertCountEqual(label_data.keys(), label_expected_fields)

        # Search
        response = self.client.get(self.url, {'search': 'Student d'})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 1)
        self.assertEqual(response.data['results'][0]['id'], self.catalog4.id)

        student = self.catalog3.student
        student.labels.add(LabelFactory(text='Label 1'))
        response = self.client.get(self.url, {'search': 'Label 1'})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 1)
        self.assertEqual(response.data['results'][0]['id'], self.catalog3.id)

        # Filters
        response = self.client.get(
            self.url, {
                'academic_program':
                self.study_class.academic_program.generic_academic_program.id
            })
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 2)
        self.assertEqual(response.data['results'][0]['id'], self.catalog3.id)
        self.assertEqual(response.data['results'][1]['id'], self.catalog4.id)

        response = self.client.get(self.url, {'study_class_grade': 'VI'})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 2)
        self.assertEqual(response.data['results'][0]['id'], self.catalog3.id)
        self.assertEqual(response.data['results'][1]['id'], self.catalog4.id)

        response = self.client.get(self.url, {'academic_year': '2018'})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 0)
    def test_pupils_statistics_admin_success(self):
        self.client.login(username=self.admin.username, password='******')
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 4)

        catalog_expected_fields = [
            'id', 'student', 'school_unit', 'avg_sem1', 'avg_sem2',
            'avg_final', 'second_examinations_count',
            'unfounded_abs_count_sem1', 'unfounded_abs_count_sem2',
            'unfounded_abs_count_annual', 'behavior_grade_sem1',
            'behavior_grade_sem2', 'behavior_grade_annual',
            'behavior_grade_limit', 'labels', 'risk_description',
            'student_in_class', 'academic_program_name'
        ]
        school_unit_expected_fields = ['id', 'name']
        label_expected_fields = ['id', 'text']
        study_class_expected_fields = ['id', 'class_grade', 'class_letter']
        for catalog_data in response.data['results']:
            self.assertCountEqual(catalog_data.keys(), catalog_expected_fields)
            self.assertCountEqual(catalog_data['school_unit'].keys(),
                                  school_unit_expected_fields)
            self.assertCountEqual(catalog_data['student_in_class'].keys(),
                                  study_class_expected_fields)
            for label_data in catalog_data['labels']:
                self.assertCountEqual(label_data.keys(), label_expected_fields)

        # Search
        student = self.catalog2.student
        student.labels.add(LabelFactory(text='Label 1'))

        response = self.client.get(self.url, {'search': 'Label 1'})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 1)
        self.assertEqual(response.data['results'][0]['id'], self.catalog2.id)
        self.assertEqual(response.data['results'][0]['behavior_grade_limit'],
                         6)

        response = self.client.get(self.url,
                                   {'search': self.another_school_unit.name})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 1)
        self.assertEqual(response.data['results'][0]['id'], self.catalog1.id)
        self.assertEqual(response.data['results'][0]['behavior_grade_limit'],
                         8)

        # Filters
        response = self.client.get(
            self.url, {
                'academic_program':
                self.study_class.academic_program.generic_academic_program.id
            })
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 2)
        self.assertEqual(response.data['results'][0]['id'], self.catalog3.id)
        self.assertEqual(response.data['results'][1]['id'], self.catalog4.id)

        response = self.client.get(self.url, {'study_class_grade': 'IX'})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 1)
        self.assertEqual(response.data['results'][0]['id'], self.catalog2.id)

        catalog = StudentCatalogPerYearFactory(
            academic_year=2018,
            student=UserProfileFactory(user_role=UserProfile.UserRoles.STUDENT,
                                       school_unit=self.school_unit))
        response = self.client.get(self.url, {'academic_year': '2018'})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 1)
        self.assertEqual(response.data['results'][0]['id'], catalog.id)