Exemplo n.º 1
0
    def test_break_day(self):
        """A break day is noted in the context and nothing is scheduled."""
        today = timezone.localdate()
        user = self.make_user()
        school_year = SchoolYearFactory(
            school=user.school,
            start_date=today + relativedelta(month=1, day=1),
            end_date=today + relativedelta(month=12, day=31),
            days_of_week=SchoolYear.ALL_DAYS,
        )
        SchoolBreakFactory(
            school_year=school_year,
            start_date=school_year.start_date,
            end_date=school_year.end_date,
        )
        enrollment = EnrollmentFactory(grade_level__school_year=school_year)
        CourseTaskFactory(course__grade_levels=[enrollment.grade_level])

        with self.login(user):
            self.get(
                "core:daily_for_date",
                year=school_year.start_date.year,
                month=school_year.start_date.month,
                day=school_year.start_date.day,
            )

        assert self.get_context("is_break_day")
        assert self.get_context("schedules") == []
Exemplo n.º 2
0
    def test_get_date_type(self):
        """Each date type has a representation."""
        today = timezone.localdate()
        single = SchoolBreakFactory.build(start_date=today, end_date=today)
        multi_day = SchoolBreakFactory.build(start_date=today,
                                             end_date=today +
                                             datetime.timedelta(days=2))

        assert single.get_date_type(today) == SchoolBreak.DateType.SINGLE
        assert multi_day.get_date_type(today) == SchoolBreak.DateType.START
        assert (multi_day.get_date_type(today + datetime.timedelta(
            days=1)) == SchoolBreak.DateType.MIDDLE)
        assert multi_day.get_date_type(
            multi_day.end_date) == SchoolBreak.DateType.END
        assert (multi_day.get_date_type(today - datetime.timedelta(
            days=1)) == SchoolBreak.DateType.NOT_A_BREAK)
Exemplo n.º 3
0
    def test_school_dates(self):
        """The dates on the report have the expected states."""
        user = self.make_user()
        enrollment = EnrollmentFactory(
            grade_level__school_year__school=user.school)
        school_year = enrollment.grade_level.school_year
        SchoolBreakFactory(
            school_year=school_year,
            start_date=school_year.start_date,
            end_date=school_year.start_date,
        )
        CourseworkFactory(
            student=enrollment.student,
            course_task__course__grade_levels=[enrollment.grade_level],
            completed_date=school_year.start_date + datetime.timedelta(days=1),
        )

        with self.login(user):
            self.get_check_200("reports:attendance", pk=enrollment.id)

        school_dates = self.get_context("school_dates")
        assert school_dates[0]["is_break"]
        assert school_dates[1]["attended"]
        assert not school_dates[4]["is_school_day"]  # First Saturday
        assert self.get_context("total_days_attended") == 1
Exemplo n.º 4
0
    def test_planned_date_accounts_for_breaks(self):
        """A planned date for a task will skip break days."""
        today = timezone.localdate()
        user = self.make_user()
        school_year = SchoolYearFactory(
            school=user.school,
            start_date=today + relativedelta(years=1, month=1, day=1),
            end_date=today + relativedelta(years=1, month=12, day=31),
            days_of_week=SchoolYear.ALL_DAYS,
        )
        SchoolBreakFactory(
            school_year=school_year,
            start_date=school_year.start_date,
            end_date=school_year.start_date,
        )
        enrollment = EnrollmentFactory(
            student__school=user.school, grade_level__school_year=school_year
        )
        course = CourseFactory(
            grade_levels=[enrollment.grade_level], days_of_week=Course.ALL_DAYS
        )
        CourseTaskFactory(course=course)

        with self.login(user):
            self.get_check_200(
                "students:course", pk=enrollment.student.id, course_id=course.id
            )

        task_item = self.get_context("task_items")[0]
        assert task_item["planned_date"] == school_year.start_date + datetime.timedelta(
            days=1
        )
Exemplo n.º 5
0
    def test_factory(self):
        school_break = SchoolBreakFactory()

        assert school_break.start_date is not None
        assert school_break.end_date is not None
        assert school_break.description != ""
        assert school_break.school_year is not None
Exemplo n.º 6
0
    def test_is_break(self):
        """A school year can check if a date is a break day."""
        school_break = SchoolBreakFactory()
        school_year = school_break.school_year

        assert school_year.is_break(school_break.start_date, student=None)
        assert not school_year.is_break(
            school_break.end_date + datetime.timedelta(days=1), student=None)
Exemplo n.º 7
0
    def test_get(self):
        user = self.make_user()
        school_break = SchoolBreakFactory(school_year__school=user.school)

        with self.login(user):
            self.get_check_200("schools:school_break_edit", pk=school_break.id)

        assert self.get_context("school_year") == school_break.school_year
Exemplo n.º 8
0
    def test_has_school_break(self):
        """A date can return an existing school break."""
        expected_school_break = SchoolBreakFactory()
        school_year = expected_school_break.school_year

        school_break = school_year.get_break(expected_school_break.start_date)

        assert school_break == expected_school_break
Exemplo n.º 9
0
    def test_post_other_user(self):
        """A user may not delete another user's break."""
        user = self.make_user()
        school_break = SchoolBreakFactory()

        with self.login(user):
            response = self.post("schools:school_break_delete", uuid=school_break.uuid)

        self.response_404(response)
Exemplo n.º 10
0
    def test_only_users_breaks(self):
        """A user can only edit their own school breaks."""
        user = self.make_user()
        school_break = SchoolBreakFactory()

        with self.login(user):
            response = self.get("schools:school_break_edit", uuid=school_break.uuid)

        self.response_404(response)
Exemplo n.º 11
0
    def test_get_break_for_all_students(self):
        """Get a break for a student for a break that applies to all students."""
        expected_school_break = SchoolBreakFactory()
        school_year = expected_school_break.school_year
        student = StudentFactory()

        school_break = school_year.get_break(expected_school_break.start_date,
                                             student=student)

        assert school_break == expected_school_break
Exemplo n.º 12
0
    def test_calendar_with_break_types(self):
        """The calendar supports single day breaks and multi-day breaks."""
        # Freeze the time because the month dates may not be deterministic
        # for fitting the dates to check into a week.
        today = datetime.date(2020, 7, 18)
        school_year = SchoolYearFactory(
            start_date=today + relativedelta(day=1),
            end_date=today + relativedelta(months=1, day=1),
        )
        SchoolBreakFactory(
            school_year=school_year,
            start_date=school_year.start_date,
            end_date=school_year.start_date,
        )
        SchoolBreakFactory(
            school_year=school_year,
            start_date=school_year.start_date + datetime.timedelta(days=1),
            end_date=school_year.start_date + datetime.timedelta(days=3),
        )
        year_calendar = YearCalendar(school_year, school_year.start_date)

        calendar = year_calendar.build()

        dates = calendar["months"][0]["weeks"][0]
        # There can be padding in the month so the test must search for the first day.
        first_date_data = {}
        first_day_index = 0
        for index, date_data in enumerate(dates):
            if date_data["day"] == 1:
                first_date_data = date_data
                first_day_index = index
                break
        assert first_date_data["school_break"] is not None
        assert first_date_data["break_style"] == "single"
        start_date_data = dates[first_day_index + 1]
        assert start_date_data["school_break"] is not None
        assert start_date_data["break_style"] == "start"
        middle_date_data = dates[first_day_index + 2]
        assert middle_date_data["school_break"] is not None
        assert middle_date_data["break_style"] == "middle"
        end_date_data = dates[first_day_index + 3]
        assert end_date_data["school_break"] is not None
        assert end_date_data["break_style"] == "end"
Exemplo n.º 13
0
    def test_get_break_for_other_student_break(self):
        """A break for another student will return None for a different student."""
        expected_school_break = SchoolBreakFactory()
        school_year = expected_school_break.school_year
        student = StudentFactory()
        other_student = StudentFactory()
        expected_school_break.students.add(other_student)

        school_break = school_year.get_break(expected_school_break.start_date,
                                             student=student)

        assert school_break is None
Exemplo n.º 14
0
    def test_post(self):
        user = self.make_user()
        school_break = SchoolBreakFactory(school_year__school=user.school)

        with self.login(user):
            response = self.post("schools:school_break_delete",
                                 pk=school_break.id)

        assert SchoolBreak.objects.count() == 0
        self.response_302(response)
        assert response.get("Location") == self.reverse(
            "schools:school_year_detail", pk=school_break.school_year.id)
Exemplo n.º 15
0
    def test_no_date_change_with_breaks(self):
        """A school year must contain any breaks."""
        school = SchoolFactory()
        school_year = SchoolYearFactory(school=school)
        start = school_year.start_date
        end = school_year.end_date
        SchoolBreakFactory(school_year=school_year, start_date=start, end_date=start)
        SchoolBreakFactory(school_year=school_year, start_date=end, end_date=end)
        data = {
            "school": str(school.id),
            "start_date": str(start + datetime.timedelta(days=1)),
            "end_date": str(end - datetime.timedelta(days=1)),
            "monday": True,
        }
        form = SchoolYearForm(user=school.admin, instance=school_year, data=data)

        is_valid = form.is_valid()

        assert not is_valid
        errors = form.non_field_errors()
        assert "You have a school break before the school year's start date." in errors
        assert "You have a school break after the school year's end date." in errors
Exemplo n.º 16
0
    def test_school_break_overlap_with_itself(self):
        """A school break is permitted to overlap with itself when updating."""
        school = SchoolFactory()
        school_break = SchoolBreakFactory(school_year__school=school)
        data = {
            "school_year": str(school_break.school_year.id),
            "start_date": str(school_break.start_date - datetime.timedelta(days=1)),
            "end_date": str(school_break.end_date),
        }
        form = SchoolBreakForm(user=school.admin, instance=school_break, data=data)

        is_valid = form.is_valid()

        assert is_valid
Exemplo n.º 17
0
    def test_post(self):
        """A user can update a school break for their school year."""
        user = self.make_user()
        school_break = SchoolBreakFactory(school_year__school=user.school)
        data = {
            "school_year": str(school_break.school_year.id),
            "description": "Christmas",
            "start_date": str(school_break.school_year.start_date),
            "end_date": str(school_break.school_year.start_date),
        }

        with self.login(user):
            response = self.post("schools:school_break_edit",
                                 pk=school_break.id,
                                 data=data)

        school_break.refresh_from_db()
        assert school_break.description == "Christmas"
        assert school_break.start_date == school_break.school_year.start_date
        assert school_break.end_date == school_break.school_year.start_date
        self.response_302(response)
        assert response.get("Location") == self.reverse(
            "schools:school_year_detail", pk=school_break.school_year.id)
Exemplo n.º 18
0
    def test_next_course_day_all_breaks(self):
        """When all school days are breaks, get the last possible course day."""
        school_year = SchoolYearFactory(days_of_week=SchoolYear.ALL_DAYS)
        grade_level = GradeLevelFactory(school_year=school_year)
        course = CourseFactory(grade_levels=[grade_level],
                               days_of_week=SchoolYear.ALL_DAYS)
        SchoolBreakFactory(
            school_year=school_year,
            start_date=school_year.start_date,
            end_date=school_year.end_date,
        )

        next_course_day = school_year.get_next_course_day(
            course, school_year.start_date, student=None)

        assert next_course_day == school_year.end_date
Exemplo n.º 19
0
    def test_next_course_day_with_break(self):
        """A break affects when the next course day is."""
        school_year = SchoolYearFactory(days_of_week=SchoolYear.ALL_DAYS)
        grade_level = GradeLevelFactory(school_year=school_year)
        course = CourseFactory(grade_levels=[grade_level],
                               days_of_week=SchoolYear.ALL_DAYS)
        SchoolBreakFactory(
            school_year=school_year,
            start_date=school_year.start_date + datetime.timedelta(days=1),
            end_date=school_year.start_date + datetime.timedelta(days=1),
        )

        next_course_day = school_year.get_next_course_day(
            course, school_year.start_date, student=None)

        assert next_course_day == school_year.start_date + datetime.timedelta(
            days=2)
Exemplo n.º 20
0
    def test_no_overlapping_breaks(self):
        """Two school breaks may not overlap."""
        school = SchoolFactory()
        school_break = SchoolBreakFactory(school_year__school=school)
        cases = [
            (
                "surround",
                str(school_break.start_date - datetime.timedelta(days=1)),
                str(school_break.end_date + datetime.timedelta(days=1)),
            ),
            (
                "inside",
                str(school_break.start_date + datetime.timedelta(days=1)),
                str(school_break.end_date - datetime.timedelta(days=1)),
            ),
            (
                "overlap_start",
                str(school_break.start_date - datetime.timedelta(days=1)),
                str(school_break.end_date - datetime.timedelta(days=1)),
            ),
            (
                "overlap_end",
                str(school_break.start_date + datetime.timedelta(days=1)),
                str(school_break.end_date + datetime.timedelta(days=1)),
            ),
        ]

        for case in cases:
            with self.subTest(case[0]):
                data = {
                    "school_year": str(school_break.school_year.id),
                    "start_date": case[1],
                    "end_date": case[2],
                }
                form = SchoolBreakForm(user=school.admin, data=data)

                is_valid = form.is_valid()

                assert not is_valid
                assert (
                    "School breaks may not have overlapping dates."
                    in form.non_field_errors()[0]
                )
Exemplo n.º 21
0
    def test_get(self):
        user = self.make_user()
        school_break = SchoolBreakFactory(school_year__school=user.school)
        # Make only one student on break.
        enrollment_1 = EnrollmentFactory(
            student__first_name="Alice",
            grade_level__school_year=school_break.school_year,
        )
        school_break.students.add(enrollment_1.student)
        enrollment_2 = EnrollmentFactory(student__first_name="Bob",
                                         grade_level=enrollment_1.grade_level)

        with self.login(user):
            self.get_check_200("schools:school_break_edit", pk=school_break.id)

        assert self.get_context("school_year") == school_break.school_year
        students = self.get_context("students")
        assert students == [enrollment_1.student, enrollment_2.student]
        assert students[0].is_on_break
        assert not students[1].is_on_break
Exemplo n.º 22
0
    def test_at_least_one_enrolled(self):
        """When students are enrolled, at least one must be on a break."""
        school = SchoolFactory()
        school_break = SchoolBreakFactory(school_year__school=school)
        enrollment = EnrollmentFactory(
            grade_level__school_year=school_break.school_year
        )
        school_break.students.add(enrollment.student)
        EnrollmentFactory(grade_level=enrollment.grade_level)
        data = {
            "school_year": str(school_break.school_year.id),
            "start_date": str(school_break.start_date),
            "end_date": str(school_break.end_date),
        }
        form = SchoolBreakForm(user=school.admin, instance=school_break, data=data)

        is_valid = form.is_valid()

        assert not is_valid
        assert "At least one student must be on break." in form.non_field_errors()[0]
Exemplo n.º 23
0
    def test_breaks_in_task_count(self):
        """A break is factored into the course task count."""
        school_year = SchoolYearFactory(days_of_week=SchoolYear.ALL_DAYS)
        grade_level = GradeLevelFactory(school_year=school_year)
        course = CourseFactory(grade_levels=[grade_level],
                               days_of_week=SchoolYear.ALL_DAYS)
        SchoolBreakFactory(
            school_year=school_year,
            start_date=school_year.start_date,
            end_date=school_year.start_date,
        )
        CourseTaskFactory(course=course)
        CourseTaskFactory(course=course)

        count = school_year.get_task_count_in_range(
            course,
            school_year.start_date,
            school_year.start_date + datetime.timedelta(days=1),
        )

        assert count == 1
Exemplo n.º 24
0
    def test_school_break_edit_switches_student_break(self):
        """A school break will switch student who is on break."""
        school = SchoolFactory()
        school_year = SchoolYearFactory(school=school)
        enrollment_1 = EnrollmentFactory(grade_level__school_year=school_year)
        enrollment_2 = EnrollmentFactory(grade_level__school_year=school_year)
        start = school_year.start_date
        school_break = SchoolBreakFactory(
            school_year=school_year, start_date=start, end_date=start
        )
        school_break.students.add(enrollment_1.student)
        data = {
            "school_year": str(school_year.id),
            "start_date": str(start),
            "end_date": str(start),
            f"student-{enrollment_2.student.id}": str(enrollment_2.student.id),
        }
        form = SchoolBreakForm(user=school.admin, instance=school_break, data=data)
        form.is_valid()

        form.save()

        assert school_break.students.first() == enrollment_2.student
Exemplo n.º 25
0
    def test_get_week_with_breaks(self):
        """Next week starts with the correct task when the current week has breaks."""
        today = timezone.now().date()
        next_week = Week(today + datetime.timedelta(days=7))
        enrollment = EnrollmentFactory()
        school_year = enrollment.grade_level.school_year
        student = enrollment.student
        course = CourseFactory(grade_levels=[enrollment.grade_level])
        CourseworkFactory(student=student,
                          course_task__course=course,
                          completed_date=today)
        task = CourseTaskFactory(course=course)
        CourseTaskFactory(course=course)
        SchoolBreakFactory(
            school_year=school_year,
            start_date=today + datetime.timedelta(days=1),
            end_date=today + datetime.timedelta(days=2),
        )

        week_schedule = student.get_week_schedule(school_year, today,
                                                  next_week)

        assert week_schedule["courses"][0]["days"][0]["task"] == task
Exemplo n.º 26
0
    def test_str(self):
        school_break = SchoolBreakFactory()

        assert str(school_break) == f"School Break {school_break.start_date}"
Exemplo n.º 27
0
 def test_unauthenticated_access(self):
     grade_level = SchoolBreakFactory()
     self.assertLoginRequired("schools:grade_level_edit",
                              uuid=grade_level.uuid)
Exemplo n.º 28
0
    def test_has_schedules(self, timezone):
        """The schedules are in the context."""
        now = datetime.datetime(2020, 1, 24, tzinfo=pytz.utc)
        friday = now.date()
        monday = friday - datetime.timedelta(days=4)
        timezone.localdate.return_value = now.date()
        user = self.make_user()
        student, grade_level = self.make_student_enrolled_in_grade_level(user, friday)
        course = CourseFactory(
            grade_levels=[grade_level],
            days_of_week=Course.MONDAY
            + Course.WEDNESDAY
            + Course.THURSDAY
            + Course.FRIDAY,
        )
        task_1 = CourseTaskFactory(course=course)
        task_2 = CourseTaskFactory(course=course)
        task_3 = CourseTaskFactory(course=course)
        coursework = CourseworkFactory(
            student=student, course_task=task_1, completed_date=monday
        )
        school_break = SchoolBreakFactory(
            school_year=grade_level.school_year,
            start_date=monday + datetime.timedelta(days=4),
            end_date=monday + datetime.timedelta(days=4),
        )

        with self.login(user), self.assertNumQueries(16):
            self.get("core:app")

        expected_schedule = {
            "student": student,
            "courses": [
                {
                    "course": course,
                    "days": [
                        {
                            "week_date": monday,
                            "coursework": [coursework],
                            "school_break": None,
                        },
                        {
                            "week_date": monday + datetime.timedelta(days=1),
                            "school_break": None,
                        },
                        {
                            "week_date": monday + datetime.timedelta(days=2),
                            "task": task_2,
                            "school_break": None,
                        },
                        {
                            "week_date": monday + datetime.timedelta(days=3),
                            "task": task_3,
                            "school_break": None,
                        },
                        {
                            "week_date": monday + datetime.timedelta(days=4),
                            "school_break": school_break,
                            "date_type": SchoolBreak.DateType.SINGLE,
                        },
                    ],
                }
            ],
        }
        schedules = self.get_context("schedules")
        assert schedules == [expected_schedule]
Exemplo n.º 29
0
 def test_unauthenticated_access(self):
     school_break = SchoolBreakFactory()
     self.assertLoginRequired("schools:school_break_edit",
                              uuid=school_break.uuid)
Exemplo n.º 30
0
 def test_unauthenticated_access(self):
     school_break = SchoolBreakFactory()
     self.assertLoginRequired("schools:school_break_delete",
                              pk=school_break.id)