class APITest(APITestCase): """ test the implementation of our API We're using Django-Rest-Framework's testing base (which extends Django's) """ def setUp(self): """ set up the testing environment """ self.populate_database() def populate_database(self): """ Extend me with more data to populate """ self.data = SisData() self.data.create_basics() def teacher_login(self): """ provides a simple way to automatically log in a teacher """ self.client.force_authenticate(user = self.data.teacher1) def student_login(self): """ provides a simple way to automatically log in a student """ self.client.force_authenticate(user = self.data.student)
class APITest(APITestCase): """ test the implementation of our API We're using Django-Rest-Framework's testing base (which extends Django's) """ def setUp(self): """ set up the testing environment """ self.populate_database() def populate_database(self): """ Extend me with more data to populate """ self.data = SisData() self.data.create_basics() self.data.create_admissions_choice_data() def teacher_login(self): """ provides a simple way to automatically log in a teacher """ self.client.force_authenticate(user = self.data.teacher1) def student_login(self): """ provides a simple way to automatically log in a student """ self.client.force_authenticate(user = self.data.student)
def setUp(self): self.data = SisData() self.data.create_basics() self.build_grade_cache() self.data.course_section1.save()
class GradeCalculationTests(SisTestMixin, TestCase): def setUp(self): self.data = SisData() self.data.create_basics() self.build_grade_cache() self.data.course_section1.save() def create_assignment(self, points_possible, category=None, assignment_type=None): return Assignment.objects.create( name="A", marking_period=self.data.marking_period, points_possible=points_possible, course_section=self.data.course_section1, category=category, assignment_type=assignment_type, ) def create_and_check_mark(self, assignment, mark, check, demonstration=None): Mark.objects.create(assignment=assignment, student=self.data.student, mark=mark, demonstration=demonstration) grade = self.data.student.grade_set.get( marking_period=self.data.marking_period, course_section=self.data.course_section1) try: check = Decimal(check) self.assertAlmostEquals(grade.get_grade(), check) except (InvalidOperation, TypeError): # Letter grade check = str(check) self.assertEquals(grade.get_grade(), check) def create_assignments(self, test_data): for data in test_data: assignment = self.create_assignment(data[0]) self.create_and_check_mark(assignment, data[1], data[2]) def create_assignments_api(self, test_data): pass # 'STUB' def test_basic_grades(self): """ Keep creating assignments for student and check the grade """ # [points_possible, points_earned, cumlative expected grade] test_data = [ [10, 5, 50], [5, 5, 66.67], [300, 0, 3.17], [50, 50, 16.44], [10, 10, 18.67], [5000, 5000, 94.33], [5000, None, 94.33], ] self.create_assignments(test_data) def test_basic_grades_edge_high(self): """ Keep creating assignments for student and check the grade checking edge cases """ test_data = [ [10, 10, 100], [10, None, 100], ] self.create_assignments(test_data) def test_basic_grades_edge_low(self): test_data = [ [10, None, ''], [10, 0, 0], ] self.create_assignments(test_data) def test_find_calculation_rule(self): year1 = SchoolYear.objects.get(name="2013-2014") year2 = SchoolYear.objects.get(name="2014-long time") year3 = SchoolYear.objects.get(name="2015-16") rule1 = CalculationRule.objects.create(first_year_effective=year1) rule2 = CalculationRule.objects.create(first_year_effective=year2) active = CalculationRule.find_active_calculation_rule() self.assertEquals(active, rule2) self.assertEquals(CalculationRule.find_calculation_rule(year1), rule1) self.assertEquals(CalculationRule.find_calculation_rule(year2), rule2) self.assertEquals(CalculationRule.find_calculation_rule(year3), rule2) def test_calculation_rule(self): CalculationRule.objects.create( first_year_effective=self.data.school_year, points_possible=4, ) test_data = [ [10, 5, 2], [5, 5, 2.67], ] self.create_assignments(test_data) self.create_assignments_api(test_data) def test_calc_rule_per_course_category_department(self): dept_eng = Department.objects.create(name="English") dept_math = Department.objects.create(name="Math") course_section = self.data.course_section1 course_section.save() course_section.course.department = dept_eng course_section.course.save() calc_rule = CalculationRule.objects.create( first_year_effective=self.data.school_year, ) cat1 = AssignmentCategory.objects.create(name="Standards") only_math_rule = CalculationRulePerCourseCategory.objects.create( category=cat1, weight=1, calculation_rule=calc_rule, ) only_math_rule.apply_to_departments.add(dept_math) only_eng_rule = CalculationRulePerCourseCategory.objects.create( category=cat1, weight=5, calculation_rule=calc_rule, ) only_eng_rule.apply_to_departments.add(dept_eng) cat2 = AssignmentCategory.objects.create(name="Engagement") all_rule = CalculationRulePerCourseCategory.objects.create( category=cat2, weight=1, calculation_rule=calc_rule, ) test_data = [ [10, 5, 50, cat1], [10, 5, 50, cat2], ] for data in test_data: assignment = self.create_assignment(data[0], category=data[3]) self.create_and_check_mark(assignment, data[1], data[2]) course_section.course.department = dept_math course_section.course.save() test_data = [ [10, 5, 50, cat1], [10, 5, 50, cat2], ] for data in test_data: assignment = self.create_assignment(data[0], category=data[3]) self.create_and_check_mark(assignment, data[1], data[2]) def test_calc_rule_per_course_category(self): calc_rule = CalculationRule.objects.create( first_year_effective=self.data.school_year, ) cat1 = AssignmentCategory.objects.create(name="Standards") cat2 = AssignmentCategory.objects.create(name="Engagement") cat3 = AssignmentCategory.objects.create(name="Engagement") CalculationRulePerCourseCategory.objects.create( category=cat1, weight=0.7, calculation_rule=calc_rule, ) CalculationRulePerCourseCategory.objects.create( category=cat2, weight=0.3, calculation_rule=calc_rule, ) CalculationRulePerCourseCategory.objects.create( category=cat3, weight=5, calculation_rule=calc_rule, ) test_data = [ [10, 0, 0, cat1], [10, 10, 30, cat2], [10, 10, 30, cat2], [30, 27, 28.2, cat2], ] for data in test_data: assignment = self.create_assignment(data[0], category=data[3]) self.create_and_check_mark(assignment, data[1], data[2]) # Test invalid weight assignment = self.create_assignment(10, category=None) self.assertRaises(WeightContainsNone, self.create_and_check_mark, assignment, 10, 66.67) def test_rule_substitution(self): course = self.data.course_section1 calc_rule = CalculationRule.objects.create( first_year_effective=self.data.school_year, ) sub_rule = CalculationRuleSubstitution.objects.create( operator='<', match_value='3.0', display_as='INC', calculation_rule=calc_rule, ) test_data = [ [4, 3, 75], [4, 2.5, 'INC'], [4, 4, 'INC'], [4, 3, 'INC'], ] for data in test_data: assignment = self.create_assignment(data[0]) self.create_and_check_mark(assignment, data[1], data[2]) def test_rule_substitution_depts(self): dept_eng = Department.objects.create(name="English") dept_math = Department.objects.create(name="Math") course = self.data.course_section1 course.course.department = dept_eng course.course.save() calc_rule = CalculationRule.objects.create( first_year_effective=self.data.school_year, ) eng_sub_rule = CalculationRuleSubstitution.objects.create( operator='<', match_value='3.0', display_as='ENG', calculation_rule=calc_rule, ) eng_sub_rule.apply_to_departments.add(dept_eng) math_sub_rule = CalculationRuleSubstitution.objects.create( operator='>=', match_value='3.0', display_as='MATH', calculation_rule=calc_rule, ) math_sub_rule.apply_to_departments.add(dept_math) test_data = [ [4, 4, 100], [4, 2.5, 'ENG'], [4, 4, 'ENG'], ] for data in test_data: assignment = self.create_assignment(data[0]) self.create_and_check_mark(assignment, data[1], data[2]) def test_assignment_type(self): type1 = AssignmentType.objects.create(name="A", weight=0.4) type2 = AssignmentType.objects.create(name="A", weight=0.5) type3 = AssignmentType.objects.create(name="A", weight=0.1) test_data = [ [10, 5, 50, type1], [10, 5, 50, type1], [10, 8, 66.67, type2], [10, 10, 70, type3], ] for data in test_data: assignment = self.create_assignment(data[0], assignment_type=data[3]) self.create_and_check_mark(assignment, data[1], data[2]) assignment = self.create_assignment(10, assignment_type=None) self.assertRaises(WeightContainsNone, self.create_and_check_mark, assignment, 10, 1) def test_assignment_type_and_category(self): type1 = AssignmentType.objects.create(name="A", weight=0.4) type2 = AssignmentType.objects.create(name="A", weight=0.6) calc_rule = CalculationRule.objects.create( first_year_effective=self.data.school_year, ) cat1 = AssignmentCategory.objects.create(name="Standards") cat2 = AssignmentCategory.objects.create(name="Engagement") CalculationRulePerCourseCategory.objects.create( category=cat1, weight=0.7, calculation_rule=calc_rule, ) CalculationRulePerCourseCategory.objects.create( category=cat2, weight=0.3, calculation_rule=calc_rule, ) test_data = [ [10, 10, 100, type1, cat1], [10, 0, 70, type1, cat2], [10, 0, 28, type2, cat1], [10, 0, 28, type2, cat2], [6, 5, 33.62, type2, cat2], ] for data in test_data: assignment = self.create_assignment(data[0], assignment_type=data[3], category=data[4]) self.create_and_check_mark(assignment, data[1], data[2]) def test_demonstration(self): cat1 = AssignmentCategory.objects.create( name="Standards", allow_multiple_demonstrations=True) cat2 = AssignmentCategory.objects.create(name="No demon") assignment1 = self.create_assignment(4, category=cat1) assignment2 = self.create_assignment(4, category=cat1) assignment3 = self.create_assignment(5, category=cat2) assignment4 = self.create_assignment(6, category=cat2) demonstration1 = Demonstration.objects.create(assignment=assignment1) demonstration2 = Demonstration.objects.create(assignment=assignment1) demonstration3 = Demonstration.objects.create(assignment=assignment1) demonstration4 = Demonstration.objects.create(assignment=assignment2) self.create_and_check_mark(assignment1, 1, 25, demonstration=demonstration1) self.create_and_check_mark(assignment1, 4, 100, demonstration=demonstration2) self.create_and_check_mark(assignment1, 2, 100, demonstration=demonstration3) self.create_and_check_mark(assignment2, 3, 87.5, demonstration=demonstration4) self.create_and_check_mark(assignment3, 3, 76.92) self.create_and_check_mark(assignment4, 4, 73.68)
def populate_database(self): """ Extend me with more data to populate """ self.data = SisData() self.data.create_basics() self.data.create_admissions_choice_data()
def populate_database(self): """ Extend me with more data to populate """ self.data = SisData() self.data.create_basics()
class GradeCalculationTests(SisTestMixin, TestCase): def setUp(self): self.data = SisData() self.data.create_basics() self.build_grade_cache() self.data.course_section1.save() def create_assignment( self, points_possible, category=None, assignment_type=None): return Assignment.objects.create( name="A", marking_period=self.data.marking_period, points_possible=points_possible, course_section=self.data.course_section1, category=category, assignment_type=assignment_type, ) def create_and_check_mark( self, assignment, mark, check, demonstration=None): Mark.objects.create( assignment=assignment, student=self.data.student, mark=mark, demonstration=demonstration ) grade = self.data.student.grade_set.get( marking_period=self.data.marking_period, course_section=self.data.course_section1) try: check = Decimal(check) self.assertAlmostEquals(grade.get_grade(), check) except (InvalidOperation, TypeError): # Letter grade check = str(check) self.assertEquals(grade.get_grade(), check) def create_assignments(self, test_data): for data in test_data: assignment = self.create_assignment(data[0]) self.create_and_check_mark(assignment, data[1], data[2]) def create_assignments_api(self, test_data): pass # 'STUB' def test_basic_grades(self): """ Keep creating assignments for student and check the grade """ # [points_possible, points_earned, cumlative expected grade] test_data = [ [10, 5, 50], [5, 5, 66.67], [300, 0, 3.17], [50, 50, 16.44], [10, 10, 18.67], [5000, 5000, 94.33], [5000, None, 94.33], ] self.create_assignments(test_data) def test_basic_grades_edge_high(self): """ Keep creating assignments for student and check the grade checking edge cases """ test_data = [ [10, 10, 100], [10, None, 100], ] self.create_assignments(test_data) def test_basic_grades_edge_low(self): test_data = [ [10, None, ''], [10, 0, 0], ] self.create_assignments(test_data) def test_find_calculation_rule(self): year1 = SchoolYear.objects.get(name="2013-2014") year2 = SchoolYear.objects.get(name="2014-long time") year3 = SchoolYear.objects.get(name="2015-16") rule1 = CalculationRule.objects.create(first_year_effective=year1) rule2 = CalculationRule.objects.create(first_year_effective=year2) active = CalculationRule.find_active_calculation_rule() self.assertEquals(active, rule2) self.assertEquals(CalculationRule.find_calculation_rule(year1), rule1) self.assertEquals(CalculationRule.find_calculation_rule(year2), rule2) self.assertEquals(CalculationRule.find_calculation_rule(year3), rule2) def test_calculation_rule(self): CalculationRule.objects.create( first_year_effective=self.data.school_year, points_possible=4, ) test_data = [ [10, 5, 2], [5, 5, 2.67], ] self.create_assignments(test_data) self.create_assignments_api(test_data) def test_calc_rule_per_course_category_department(self): dept_eng = Department.objects.create(name="English") dept_math = Department.objects.create(name="Math") course_section = self.data.course_section1 course_section.save() course_section.course.department = dept_eng course_section.course.save() calc_rule = CalculationRule.objects.create( first_year_effective=self.data.school_year, ) cat1 = AssignmentCategory.objects.create(name="Standards") only_math_rule = CalculationRulePerCourseCategory.objects.create( category=cat1, weight=1, calculation_rule=calc_rule, ) only_math_rule.apply_to_departments.add(dept_math) only_eng_rule = CalculationRulePerCourseCategory.objects.create( category=cat1, weight=5, calculation_rule=calc_rule, ) only_eng_rule.apply_to_departments.add(dept_eng) cat2 = AssignmentCategory.objects.create(name="Engagement") all_rule = CalculationRulePerCourseCategory.objects.create( category=cat2, weight=1, calculation_rule=calc_rule, ) test_data = [ [10, 5, 50, cat1], [10, 5, 50, cat2], ] for data in test_data: assignment = self.create_assignment(data[0], category=data[3]) self.create_and_check_mark(assignment, data[1], data[2]) course_section.course.department = dept_math course_section.course.save() test_data = [ [10, 5, 50, cat1], [10, 5, 50, cat2], ] for data in test_data: assignment = self.create_assignment(data[0], category=data[3]) self.create_and_check_mark(assignment, data[1], data[2]) def test_calc_rule_per_course_category(self): calc_rule = CalculationRule.objects.create( first_year_effective=self.data.school_year, ) cat1 = AssignmentCategory.objects.create(name="Standards") cat2 = AssignmentCategory.objects.create(name="Engagement") cat3 = AssignmentCategory.objects.create(name="Engagement") CalculationRulePerCourseCategory.objects.create( category=cat1, weight=0.7, calculation_rule=calc_rule, ) CalculationRulePerCourseCategory.objects.create( category=cat2, weight=0.3, calculation_rule=calc_rule, ) CalculationRulePerCourseCategory.objects.create( category=cat3, weight=5, calculation_rule=calc_rule, ) test_data = [ [10, 0, 0, cat1], [10, 10, 30, cat2], [10, 10, 30, cat2], [30, 27, 28.2, cat2], ] for data in test_data: assignment = self.create_assignment(data[0], category=data[3]) self.create_and_check_mark(assignment, data[1], data[2]) # Test invalid weight assignment = self.create_assignment( 10, category=None) self.assertRaises( WeightContainsNone, self.create_and_check_mark, assignment, 10, 66.67) def test_rule_substitution(self): course = self.data.course_section1 calc_rule = CalculationRule.objects.create( first_year_effective=self.data.school_year, ) sub_rule = CalculationRuleSubstitution.objects.create( operator='<', match_value='3.0', display_as='INC', calculation_rule=calc_rule, ) test_data = [ [4, 3, 75], [4, 2.5, 'INC'], [4, 4, 'INC'], [4, 3, 'INC'], ] for data in test_data: assignment = self.create_assignment(data[0]) self.create_and_check_mark(assignment, data[1], data[2]) def test_rule_substitution_depts(self): dept_eng = Department.objects.create(name="English") dept_math = Department.objects.create(name="Math") course = self.data.course_section1 course.course.department = dept_eng course.course.save() calc_rule = CalculationRule.objects.create( first_year_effective=self.data.school_year, ) eng_sub_rule = CalculationRuleSubstitution.objects.create( operator='<', match_value='3.0', display_as='ENG', calculation_rule=calc_rule, ) eng_sub_rule.apply_to_departments.add(dept_eng) math_sub_rule = CalculationRuleSubstitution.objects.create( operator='>=', match_value='3.0', display_as='MATH', calculation_rule=calc_rule, ) math_sub_rule.apply_to_departments.add(dept_math) test_data = [ [4, 4, 100], [4, 2.5, 'ENG'], [4, 4, 'ENG'], ] for data in test_data: assignment = self.create_assignment(data[0]) self.create_and_check_mark(assignment, data[1], data[2]) def test_assignment_type(self): type1 = AssignmentType.objects.create(name="A", weight=0.4) type2 = AssignmentType.objects.create(name="A", weight=0.5) type3 = AssignmentType.objects.create(name="A", weight=0.1) test_data = [ [10, 5, 50, type1], [10, 5, 50, type1], [10, 8, 66.67, type2], [10, 10, 70, type3], ] for data in test_data: assignment = self.create_assignment( data[0], assignment_type=data[3]) self.create_and_check_mark(assignment, data[1], data[2]) assignment = self.create_assignment( 10, assignment_type=None) self.assertRaises( WeightContainsNone, self.create_and_check_mark, assignment, 10, 1) def test_assignment_type_and_category(self): type1 = AssignmentType.objects.create(name="A", weight=0.4) type2 = AssignmentType.objects.create(name="A", weight=0.6) calc_rule = CalculationRule.objects.create( first_year_effective=self.data.school_year, ) cat1 = AssignmentCategory.objects.create(name="Standards") cat2 = AssignmentCategory.objects.create(name="Engagement") CalculationRulePerCourseCategory.objects.create( category=cat1, weight=0.7, calculation_rule=calc_rule, ) CalculationRulePerCourseCategory.objects.create( category=cat2, weight=0.3, calculation_rule=calc_rule, ) test_data = [ [10, 10, 100, type1, cat1], [10, 0, 70, type1, cat2], [10, 0, 28, type2, cat1], [10, 0, 28, type2, cat2], [6, 5, 33.62, type2, cat2], ] for data in test_data: assignment = self.create_assignment( data[0], assignment_type=data[3], category=data[4]) self.create_and_check_mark(assignment, data[1], data[2]) def test_demonstration(self): cat1 = AssignmentCategory.objects.create( name="Standards", allow_multiple_demonstrations=True) cat2 = AssignmentCategory.objects.create(name="No demon") assignment1 = self.create_assignment(4, category=cat1) assignment2 = self.create_assignment(4, category=cat1) assignment3 = self.create_assignment(5, category=cat2) assignment4 = self.create_assignment(6, category=cat2) demonstration1 = Demonstration.objects.create(assignment=assignment1) demonstration2 = Demonstration.objects.create(assignment=assignment1) demonstration3 = Demonstration.objects.create(assignment=assignment1) demonstration4 = Demonstration.objects.create(assignment=assignment2) self.create_and_check_mark( assignment1, 1, 25, demonstration=demonstration1) self.create_and_check_mark( assignment1, 4, 100, demonstration=demonstration2) self.create_and_check_mark( assignment1, 2, 100, demonstration=demonstration3) self.create_and_check_mark( assignment2, 3, 87.5, demonstration=demonstration4) self.create_and_check_mark(assignment3, 3, 76.92) self.create_and_check_mark(assignment4, 4, 73.68)
class GradeCalculationTests(SisTestMixin, TestCase): def setUp(self): self.data = SisData() self.data.create_basics() self.build_grade_cache() def test_course_average_respect_time(self): """ See /docs/specs/course_grades.md#Time and averages mp1 start_date=`2014-07-1` and end_date=`2014-9-1` mp2 start_date=`2014-9-2` and end_date=`2015-3-1` """ mark1 = 50 mark2 = 100 student = self.data.student mp1 = self.data.marking_period mp2 = self.data.marking_period2 section = self.data.course_section1 enroll = self.data.course_enrollment grade1, created = Grade.objects.get_or_create( student=student, course_section=section, marking_period=mp1, grade=mark1, ) grade2, created = Grade.objects.get_or_create( student=student, course_section=section, marking_period=mp2, grade=mark2, ) self.assertEquals( enroll.get_grade(date_report=datetime.date(2099, 1, 1)), 75) self.assertEquals( enroll.get_grade(date_report=datetime.date(2014, 10, 1)), 50) # Test compares two ways of calling calculate_grade() # There shouldn't be a discrepancy def test_current_vs_older(self): self.student = Student(first_name='Billy', last_name='Bob', username='******', id=12345) self.student.save() self.year = SchoolYear(name='2011-2012', start_date='2011-09-10', end_date='2012-06-15', grad_date='2012-06-17', id=2011) self.year.save() self.mp = MarkingPeriod(name="tri1 2011", start_date='2011-09-10', end_date='2012-06-15', school_year=self.year, monday=True, friday=True) self.mp.save() self.mp2 = MarkingPeriod(name="tri2 2012", start_date='2011-09-10', end_date='2012-06-15', school_year=self.year, monday=True, friday=True) self.mp2.save() self.mp3 = MarkingPeriod(name="tri3 2012", start_date='2011-09-10', end_date='2012-06-15', school_year=self.year, monday=True, friday=True) self.mp3.save() courses = [ Course(fullname='Algebra', shortname='alg', id=12, credits=4), Course(fullname='English', shortname='eng', id=13, credits=4), Course(fullname='History', shortname='hist', id=14, credits=4) ] course_sections = [] for course in courses: course.save() course_section = CourseSection(course=course, name=course.fullname) course_section.save() course_sections.append(course_section) course_sections[0].marking_period.add(self.mp) course_sections[1].marking_period.add(self.mp2) course_sections[2].marking_period.add(self.mp3) grades = [ Grade(student=self.student, course_section=course_sections[0], grade=86.78, marking_period=self.mp), Grade(student=self.student, course_section=course_sections[1], grade=94.73, marking_period=self.mp2), Grade(student=self.student, course_section=course_sections[2], grade=77.55, marking_period=self.mp3) ] for grade in grades: grade.save() course_enrollments = [ CourseEnrollment(user=self.student, course_section=course_sections[0], grade=grades[0]), CourseEnrollment(user=self.student, course_section=course_sections[1], grade=grades[1]), CourseEnrollment(user=self.student, course_section=course_sections[2], grade=grades[2]) ] for course_enrollment in course_enrollments: course_enrollment.save() StudentYearGrade.objects.create(student=self.student, year=self.year) syg = self.student.studentyeargrade_set.get(year=self.year) current = syg.calculate_grade_and_credits( date_report=datetime.date.today()) older = syg.calculate_grade_and_credits() self.assertEqual(current, older)
class GradeBaltTests(SisTestMixin, TestCase): """ These test ensure we meet requirements defined by Cristo Rey Baltimore including Grade scales, course weights, and letter grades Sample data is anonomized real grade data """ def populate_database(self): """ Override, not using traditional test data """ self.data = SisData() self.data.create_grade_scale_data() self.data.create_sample_honors_and_ap_data() self.build_grade_cache() def test_letter_grade(self): mp1 = self.data.mp1 mp2 = self.data.mp2 mp3 = self.data.mp3 mp4 = self.data.mp4 test_data = [ [mp1, 1, 'C'], [mp1, 2, 'F'], [mp1, 3, 'F'], [mp1, 4, 'A-'], [mp1, 5, 'B-'], [mp1, 6, 'A'], [mp1, 7, 'B-'], [mp1, 8, 'A'], [mp2, 1, 'C+'], [mp2, 2, 'B-'], [mp2, 3, 'D'], [mp2, 4, 'B'], [mp2, 5, 'D'], [mp2, 6, 'A'], [mp2, 7, 'B'], [mp2, 8, 'A'], [mp3, 1, 'F'], [mp3, 2, 'C'], [mp3, 3, 'C'], [mp3, 4, 'C'], [mp3, 5, 'C'], [mp3, 6, 'B'], [mp3, 7, 'C+'], [mp3, 8, 'A'], [mp4, 1, 'C'], [mp4, 2, 'C+'], [mp4, 3, 'D'], [mp4, 4, 'B+'], [mp4, 5, 'B'], [mp4, 6, 'A-'], [mp4, 7, 'B+'], [mp4, 8, 'A'], ] for x in test_data: grade = Grade.objects.get( student = self.data.student, marking_period=x[0], course_section_id=x[1] ) self.assertEqual(grade.get_grade(letter=True), x[2]) def test_snx_grade(self): """ Really just a normal run of the mill Marking Period grade Balt uses s1x, s2x as tests that affect final grades """ grade = Grade.objects.get(marking_period=self.data.mps1x, course_section_id=1) self.assertEqual(grade.get_grade(), 90) grade = Grade.objects.get(marking_period=self.data.mps2x, course_section_id=1) self.assertEqual(grade.get_grade(), 79) def test_partial_course_average_grade(self): """ Tests getting the average of some but not all marking period averages """ s1_ids = [1,2,3] s2_ids = [4,5,6] test_data = [ [1, s1_ids, 78.08, 'C+'], [1, s2_ids, 71.96, 'D'], [2, s1_ids, 68.16, 'F'], [2, s2_ids, 70.84, 'D'], [3, s1_ids, 68.0, 'F'], [3, s2_ids, 69.84, 'D'], [4, s1_ids, 87.52, 'B+'], [4, s2_ids, 80.88, 'B-'], [5, s1_ids, 73.6, 'C'], [5, s2_ids, 80.08, 'B-'], [6, s1_ids, 93.2, 'A'], [6, s2_ids, 86.65, 'B+'], [7, s1_ids, 79.04, 'C+'], [7, s2_ids, 83.12, 'B'], [8, s1_ids, 100, 'A'], [8, s2_ids, 100, 'A'], ] for x in test_data: ce = CourseEnrollment.objects.get(user=self.data.student, course_section=x[0]) self.assertAlmostEqual(ce.get_average_for_marking_periods(x[1]), Decimal(x[2])) self.assertEqual(ce.get_average_for_marking_periods(x[1], letter=True), x[3]) def test_scaled_average(self): """ Tests an asinine method for averages by converting to non linear scale first """ test_data = [ [1, Decimal(2.0)], [2, Decimal(2.4)], [4, Decimal(1.9)], [5, Decimal(2.8)], ] for x in test_data: smpg = StudentMarkingPeriodGrade.objects.get(student=self.data.student, marking_period=x[0]) self.assertAlmostEqual(smpg.get_scaled_average(rounding=1), x[1]) def test_average(self): test_data = [ [3, 72.7], [6, 71.8], ] for x in test_data: smpg = StudentMarkingPeriodGrade.objects.get(student=self.data.student, marking_period=x[0]) self.assertAlmostEqual(smpg.get_average(rounding=1), Decimal(x[1])) def test_scaled_multiple_mp_average(self): test_data = [ [[1, 2, 3], Decimal(1.9)], [[4, 5, 6], Decimal(2.1)], ] for x in test_data: average = Grade.get_scaled_multiple_mp_average(self.data.student, x[0], rounding=1) self.assertAlmostEqual(average, x[1]) def test_scaled_final_year_average(self): test_data = [ [1, Decimal(2.2)], ] for x in test_data: year_grade = self.data.student.studentyeargrade_set.get(year=x[0]) average = year_grade.get_grade(numeric_scale=True, rounding=1, prescale=True) self.assertAlmostEqual(average, x[1]) def test_balt_gpa(self): gpa = self.data.student.calculate_gpa(rounding=1, prescale=True) self.assertAlmostEqual(gpa, Decimal(2.2)) def test_final_grade(self): test_data = [ [1, 'C'], [2, 'D'], [3, 'D'], [4, 'B'], [5, 'C+'], [6, 'A-'], [7, 'B-'], [8, 'A'], ] for x in test_data: ce = CourseEnrollment.objects.get(user=self.data.student, course_section=x[0]) with self.assertNumQueries(1): self.assertEqual(ce.get_grade(letter=True), x[1]) def test_honors_and_ap_scaled_grades(self): """ assert that the honors and ap grades receive correct boost by replicating the grades in our manual spreadsheet """ # Now, test that the scaled averages are correct test_data = [ {'mp_id': 1, 'boosted': Decimal(4.0), 'unboosted': Decimal(3.7)}, {'mp_id': 2, 'boosted': Decimal(3.6), 'unboosted': Decimal(3.3)}, {'mp_id': 4, 'boosted': Decimal(3.7), 'unboosted': Decimal(3.4)}, {'mp_id': 5, 'boosted': Decimal(3.5), 'unboosted': Decimal(3.2)} ] for x in test_data: smpg = StudentMarkingPeriodGrade.objects.get(student=self.data.honors_student, marking_period=x['mp_id']) self.assertAlmostEqual(smpg.get_scaled_average(rounding=1), x['boosted']) self.assertAlmostEqual(smpg.get_scaled_average(rounding=1, boost=False), x['unboosted']) def test_honors_and_ap_student_year_grade(self): """ assert that the end of the year grade is correct """ # try without pre-scaling year_grade = self.data.honors_student.studentyeargrade_set.get(year=1) average = year_grade.get_grade(numeric_scale=True, rounding=1) self.assertAlmostEqual(average, Decimal(3.8)) # try with pre-scaling year_grade = self.data.honors_student.studentyeargrade_set.get(year=1) average = year_grade.get_grade(numeric_scale=True, rounding=1, prescale=True) self.assertAlmostEqual(average, Decimal(3.6)) # try with pre-scaling but without boost year_grade = self.data.honors_student.studentyeargrade_set.get(year=1) average = year_grade.get_grade(numeric_scale=True, rounding=1, prescale=True, boost=False) self.assertAlmostEqual(average, Decimal(3.3)) def test_honors_and_ap_letter_grades(self): """ assert that the end-of-semester and final letter grades are correct for individual course sections that is... """ expected_grades = [ {'section': 'English-H', 's1': 'B+', 's2': 'B', 'final': 'B' }, {'section': 'Precalc-H', 's1': 'B', 's2': 'B-', 'final': 'B' }, {'section': 'Phys', 's1': 'A-', 's2': 'A-', 'final': 'A-'}, {'section': 'Hist-AP', 's1': 'B-', 's2': 'B', 'final': 'B' }, {'section': 'Span', 's1': 'A-', 's2': 'B', 'final': 'B+'}, {'section': 'Photo', 's1': 'A', 's2': 'A', 'final': 'A' }, {'section': 'Faith', 's1': 'B+', 's2': 'A-', 'final': 'B+'}, {'section': 'Wrt Lab', 's1': 'A', 's2': 'A', 'final': 'A' } ] # first check final grades for x in expected_grades: section = CourseSection.objects.get(name = x['section']) ce = CourseEnrollment.objects.get( user = self.data.honors_student, course_section = section, ) with self.assertNumQueries(1): self.assertEqual(ce.get_grade(letter=True), x['final']) sm1_grade = ce.get_average_for_marking_periods( marking_periods = [1,2,3], letter = True, ) sm2_grade = ce.get_average_for_marking_periods( marking_periods = [4,5,6], letter = True, ) self.assertEqual(sm1_grade, x['s1']) self.assertEqual(sm2_grade, x['s2']) def test_honors_student_gpa(self): """ test that the student's gpa after 1 year is correct! """ gpa = self.data.honors_student.calculate_gpa(rounding=1, prescale=True) self.assertAlmostEqual(gpa, Decimal(3.6))
def populate_database(self): """ Override, not using traditional test data """ self.data = SisData() self.data.create_grade_scale_data() self.data.create_sample_honors_and_ap_data() self.build_grade_cache()
class GradeBaltTests(SisTestMixin, TestCase): """ These test ensure we meet requirements defined by Cristo Rey Baltimore including Grade scales, course weights, and letter grades Sample data is anonomized real grade data """ def populate_database(self): """ Override, not using traditional test data """ self.data = SisData() self.data.create_grade_scale_data() self.data.create_sample_honors_and_ap_data() self.build_grade_cache() def test_letter_grade(self): mp1 = self.data.mp1 mp2 = self.data.mp2 mp3 = self.data.mp3 mp4 = self.data.mp4 test_data = [ [mp1, 1, 'C'], [mp1, 2, 'F'], [mp1, 3, 'F'], [mp1, 4, 'A-'], [mp1, 5, 'B-'], [mp1, 6, 'A'], [mp1, 7, 'B-'], [mp1, 8, 'A'], [mp2, 1, 'C+'], [mp2, 2, 'B-'], [mp2, 3, 'D'], [mp2, 4, 'B'], [mp2, 5, 'D'], [mp2, 6, 'A'], [mp2, 7, 'B'], [mp2, 8, 'A'], [mp3, 1, 'F'], [mp3, 2, 'C'], [mp3, 3, 'C'], [mp3, 4, 'C'], [mp3, 5, 'C'], [mp3, 6, 'B'], [mp3, 7, 'C+'], [mp3, 8, 'A'], [mp4, 1, 'C'], [mp4, 2, 'C+'], [mp4, 3, 'D'], [mp4, 4, 'B+'], [mp4, 5, 'B'], [mp4, 6, 'A-'], [mp4, 7, 'B+'], [mp4, 8, 'A'], ] for x in test_data: grade = Grade.objects.get( student = self.data.student, marking_period=x[0], course_section=getattr(self.data, 'course_section' + str(x[1])) ) self.assertEqual(grade.get_grade(letter=True), x[2]) def test_snx_grade(self): """ Really just a normal run of the mill Marking Period grade Balt uses s1x, s2x as tests that affect final grades """ grade = Grade.objects.get(marking_period=self.data.mps1x, course_section=self.data.course_section1) self.assertEqual(grade.get_grade(), 90) grade = Grade.objects.get(marking_period=self.data.mps2x, course_section=self.data.course_section1) self.assertEqual(grade.get_grade(), 79) def test_partial_course_average_grade(self): """ Tests getting the average of some but not all marking period averages """ s1_ids = [self.data.mp1.id ,self.data.mp2.id ,self.data.mps1x.id] s2_ids = [self.data.mp3.id ,self.data.mp4.id ,self.data.mps2x.id] test_data = [ [1, s1_ids, 78.08, 'C+'], [1, s2_ids, 71.96, 'D'], [2, s1_ids, 68.16, 'F'], [2, s2_ids, 70.84, 'D'], [3, s1_ids, 68.0, 'F'], [3, s2_ids, 69.84, 'D'], [4, s1_ids, 87.52, 'B+'], [4, s2_ids, 80.88, 'B-'], [5, s1_ids, 73.6, 'C'], [5, s2_ids, 80.08, 'B-'], [6, s1_ids, 93.2, 'A'], [6, s2_ids, 86.65, 'B+'], [7, s1_ids, 79.04, 'C+'], [7, s2_ids, 83.12, 'B'], [8, s1_ids, 100, 'A'], [8, s2_ids, 100, 'A'], ] for x in test_data: ce = CourseEnrollment.objects.get(user=self.data.student, course_section=getattr(self.data, 'course_section' + str(x[0]))) self.assertAlmostEqual(ce.get_average_for_marking_periods(x[1]), Decimal(x[2])) self.assertEqual(ce.get_average_for_marking_periods(x[1], letter=True), x[3]) def test_scaled_average(self): """ Tests an asinine method for averages by converting to non linear scale first """ test_data = [ [self.data.mp1, Decimal(2.0)], [self.data.mp2, Decimal(2.4)], [self.data.mp3, Decimal(1.9)], [self.data.mp4, Decimal(2.8)], ] for x in test_data: smpg = StudentMarkingPeriodGrade.objects.get(student=self.data.student, marking_period=x[0]) self.assertAlmostEqual(smpg.get_scaled_average(rounding=1), x[1]) def test_average(self): test_data = [ [self.data.mps1x, 72.7], [self.data.mps2x, 71.8], ] for x in test_data: smpg = StudentMarkingPeriodGrade.objects.get(student=self.data.student, marking_period=x[0]) self.assertAlmostEqual(smpg.get_average(rounding=1), Decimal(x[1])) def test_scaled_multiple_mp_average(self): test_data = [ [[self.data.mp1.id, self.data.mp2.id, self.data.mps1x.id], Decimal(1.9)], [[self.data.mp3.id, self.data.mp4.id, self.data.mps2x.id], Decimal(2.1)], ] for x in test_data: average = Grade.get_scaled_multiple_mp_average(self.data.student, x[0], rounding=1) self.assertAlmostEqual(average, x[1]) def test_scaled_final_year_average(self): test_data = [ [self.data.year, Decimal(2.2)], ] for x in test_data: year_grade = self.data.student.studentyeargrade_set.get(year=x[0]) average = year_grade.get_grade(numeric_scale=True, rounding=1, prescale=True) self.assertAlmostEqual(average, x[1]) def test_balt_gpa(self): gpa = self.data.student.calculate_gpa(rounding=1, prescale=True) self.assertAlmostEqual(gpa, Decimal(2.2)) def test_final_grade(self): test_data = [ [1, 'C'], [2, 'D'], [3, 'D'], [4, 'B'], [5, 'C+'], [6, 'A-'], [7, 'B-'], [8, 'A'], ] for x in test_data: ce = CourseEnrollment.objects.get( user=self.data.student, course_section=getattr(self.data, 'course_section' + str(x[0]))) with self.assertNumQueries(1): self.assertEqual(ce.get_grade(letter=True), x[1]) def test_honors_and_ap_scaled_grades(self): """ assert that the honors and ap grades receive correct boost by replicating the grades in our manual spreadsheet """ # Now, test that the scaled averages are correct test_data = [ {'mp': self.data.mp1, 'boosted': Decimal(4.0), 'unboosted': Decimal(3.7)}, {'mp': self.data.mp2, 'boosted': Decimal(3.6), 'unboosted': Decimal(3.3)}, {'mp': self.data.mp3, 'boosted': Decimal(3.7), 'unboosted': Decimal(3.4)}, {'mp': self.data.mp4, 'boosted': Decimal(3.5), 'unboosted': Decimal(3.2)} ] for x in test_data: smpg = StudentMarkingPeriodGrade.objects.get(student=self.data.honors_student, marking_period=x['mp']) self.assertAlmostEqual(smpg.get_scaled_average(rounding=1), x['boosted']) self.assertAlmostEqual(smpg.get_scaled_average(rounding=1, boost=False), x['unboosted']) def test_honors_and_ap_student_year_grade(self): """ assert that the end of the year grade is correct """ # try without pre-scaling year_grade = self.data.honors_student.studentyeargrade_set.get(year=self.data.year) average = year_grade.get_grade(numeric_scale=True, rounding=1) self.assertAlmostEqual(average, Decimal(3.8)) # try with pre-scaling year_grade = self.data.honors_student.studentyeargrade_set.get(year=self.data.year) average = year_grade.get_grade(numeric_scale=True, rounding=1, prescale=True) self.assertAlmostEqual(average, Decimal(3.6)) # try with pre-scaling but without boost year_grade = self.data.honors_student.studentyeargrade_set.get(year=self.data.year) average = year_grade.get_grade(numeric_scale=True, rounding=1, prescale=True, boost=False) self.assertAlmostEqual(average, Decimal(3.3)) def test_honors_and_ap_letter_grades(self): """ assert that the end-of-semester and final letter grades are correct for individual course sections that is... """ expected_grades = [ {'section': 'English-H', 's1': 'B+', 's2': 'B', 'final': 'B' }, {'section': 'Precalc-H', 's1': 'B', 's2': 'B-', 'final': 'B' }, {'section': 'Phys', 's1': 'A-', 's2': 'A-', 'final': 'A-'}, {'section': 'Hist-AP', 's1': 'B-', 's2': 'B', 'final': 'B' }, {'section': 'Span', 's1': 'A-', 's2': 'B', 'final': 'B+'}, {'section': 'Photo', 's1': 'A', 's2': 'A', 'final': 'A' }, {'section': 'Faith', 's1': 'B+', 's2': 'A-', 'final': 'B+'}, {'section': 'Wrt Lab', 's1': 'A', 's2': 'A', 'final': 'A' } ] # first check final grades for x in expected_grades: section = CourseSection.objects.get(name = x['section']) ce = CourseEnrollment.objects.get( user = self.data.honors_student, course_section = section, ) with self.assertNumQueries(1): self.assertEqual(ce.get_grade(letter=True), x['final']) sm1_grade = ce.get_average_for_marking_periods( marking_periods = [self.data.mp1.id, self.data.mp2.id, self.data.mps1x.id], letter = True, ) sm2_grade = ce.get_average_for_marking_periods( marking_periods = [self.data.mp3.id, self.data.mp4.id, self.data.mps2x.id], letter = True, ) self.assertEqual(sm1_grade, x['s1']) self.assertEqual(sm2_grade, x['s2']) def test_honors_student_gpa(self): """ test that the student's gpa after 1 year is correct! """ gpa = self.data.honors_student.calculate_gpa(rounding=1, prescale=True) self.assertAlmostEqual(gpa, Decimal(3.6))
def setUp(self): self.data = SisData() self.data.create_basics() self.build_grade_cache()
class GradeCalculationTests(SisTestMixin, TestCase): def setUp(self): self.data = SisData() self.data.create_basics() self.build_grade_cache() def test_course_average_respect_time(self): """ See /docs/specs/course_grades.md#Time and averages mp1 start_date=`2014-07-1` and end_date=`2014-9-1` mp2 start_date=`2014-9-2` and end_date=`2015-3-1` """ mark1 = 50 mark2 = 100 student = self.data.student mp1 = self.data.marking_period mp2 = self.data.marking_period2 section = self.data.course_section1 enroll = self.data.course_enrollment grade1, created = Grade.objects.get_or_create( student=student, course_section=section, marking_period=mp1, grade=mark1,) grade2, created = Grade.objects.get_or_create( student=student, course_section=section, marking_period=mp2, grade=mark2,) self.assertEquals( enroll.get_grade(date_report=datetime.date(2099, 1, 1)), 75) self.assertEquals( enroll.get_grade(date_report=datetime.date(2014, 10, 1)), 50) # Test compares two ways of calling calculate_grade() # There shouldn't be a discrepancy def test_current_vs_older(self): self.student = Student(first_name='Billy', last_name='Bob', username='******', id=12345) self.student.save() self.year = SchoolYear(name='2011-2012', start_date='2011-09-10', end_date='2012-06-15', grad_date='2012-06-17', id=2011) self.year.save() self.mp = MarkingPeriod(name="tri1 2011", start_date='2011-09-10', end_date='2012-06-15', school_year=self.year, monday=True, friday=True) self.mp.save() self.mp2 = MarkingPeriod(name="tri2 2012", start_date='2011-09-10', end_date='2012-06-15', school_year=self.year, monday=True, friday=True) self.mp2.save() self.mp3 = MarkingPeriod(name="tri3 2012", start_date='2011-09-10', end_date='2012-06-15', school_year=self.year, monday=True, friday=True) self.mp3.save() courses = [Course(fullname='Algebra', shortname='alg', id=12, credits=4), Course(fullname='English', shortname='eng', id=13, credits=4), Course(fullname='History', shortname='hist', id=14, credits=4)] course_sections = [] for course in courses: course.save() course_section = CourseSection( course=course, name=course.fullname ) course_section.save() course_sections.append(course_section) course_sections[0].marking_period.add(self.mp) course_sections[1].marking_period.add(self.mp2) course_sections[2].marking_period.add(self.mp3) grades = [ Grade( student=self.student, course_section=course_sections[0], grade=86.78, marking_period=self.mp ), Grade( student=self.student, course_section=course_sections[1], grade=94.73, marking_period=self.mp2 ), Grade( student=self.student, course_section=course_sections[2], grade=77.55, marking_period=self.mp3 ) ] for grade in grades: grade.save() course_enrollments = [ CourseEnrollment(user=self.student, course_section=course_sections[0], grade=grades[0]), CourseEnrollment(user=self.student, course_section=course_sections[1], grade=grades[1]), CourseEnrollment(user=self.student, course_section=course_sections[2], grade=grades[2]) ] for course_enrollment in course_enrollments: course_enrollment.save() StudentYearGrade.objects.create(student=self.student, year=self.year) syg = self.student.studentyeargrade_set.get(year=self.year) current = syg.calculate_grade_and_credits(date_report=datetime.date.today()) older = syg.calculate_grade_and_credits() self.assertEqual(current, older)
def populate_database(self): """ Override, not using traditional test data """ self.data = SisData() self.data.create_balt_like_sample_data() self.build_grade_cache()