Beispiel #1
0
    def test_replicates_with_autonumber(self):
        """A user who replicates with autonumber will create multiple numbered tasks."""
        user = self.make_user()
        grade_level = GradeLevelFactory(school_year__school=user.school)
        course = CourseFactory(grade_levels=[grade_level])
        data = {
            "course": str(course.id),
            "description": "A new task",
            "duration": "30",
            "replicate": "on",
            "replicate_count": "2",
            "autonumber": "on",
        }

        with self.login(user):
            self.post("courses:task_create", pk=course.id, data=data)

        assert CourseTask.objects.count() == 2
        descriptions = list(
            CourseTask.objects.filter(course=course).values_list("description",
                                                                 flat=True))
        assert descriptions == ["A new task 1", "A new task 2"]
Beispiel #2
0
    def test_has_tasks_today(self):
        """A course that runs today shows its tasks."""
        user = self.make_user()
        enrollment = EnrollmentFactory(
            student__school=user.school,
            grade_level__school_year__school=user.school)
        student = enrollment.student
        grade_level = enrollment.grade_level
        course = CourseFactory(grade_levels=[grade_level])
        task = CourseTaskFactory(course=course)
        today = timezone.now().date()

        with self.login(user):
            self.get("students:course",
                     uuid=student.uuid,
                     course_uuid=course.uuid)

        assert self.get_context("task_items") == [{
            "course_task": task,
            "planned_date": today,
            "has_graded_work": False
        }]
Beispiel #3
0
    def test_only_task_for_grade_level(self):
        """Only general tasks and tasks for the student's grade level appear."""
        user = self.make_user()
        enrollment = EnrollmentFactory(
            student__school=user.school, grade_level__school_year__school=user.school
        )
        course = CourseFactory(grade_levels=[enrollment.grade_level])
        general_task = CourseTaskFactory(course=course)
        grade_level_task = CourseTaskFactory(
            course=course, grade_level=enrollment.grade_level
        )
        CourseTaskFactory(course=course, grade_level=GradeLevelFactory())

        with self.login(user):
            self.get_check_200(
                "students:course", uuid=enrollment.student.uuid, course_uuid=course.uuid
            )

        task_items = self.get_context("task_items")
        assert len(task_items) == 2
        assert task_items[0]["course_task"] == general_task
        assert task_items[1]["course_task"] == grade_level_task
    def test_grade_next(self):
        """A graded task sends the user to the grade page after submission."""
        user = self.make_user()
        student = StudentFactory(school=user.school)
        grade_level = GradeLevelFactory(school_year__school=user.school)
        EnrollmentFactory(student=student, grade_level=grade_level)
        course = CourseFactory(grade_levels=[grade_level])
        course_task = CourseTaskFactory(course=course)
        GradedWorkFactory(course_task=course_task)
        data = {"completed_date": str(grade_level.school_year.start_date)}

        with self.login(user):
            response = self.post(
                "students:coursework",
                pk=student.id,
                course_task_id=course_task.id,
                data=data,
            )

        self.response_302(response)
        grade_url = self.reverse("students:grade")
        assert grade_url in response.get("Location")
    def test_post(self):
        """A POST creates a grade."""
        user = self.make_user()
        student = StudentFactory(school=user.school)
        grade_level = GradeLevelFactory(school_year__school=user.school)
        EnrollmentFactory(student=student, grade_level=grade_level)
        course = CourseFactory(grade_levels=[grade_level])
        course_task = CourseTaskFactory(course=course)
        graded_work = GradedWorkFactory(course_task=course_task)
        data = {"score": "100"}

        with self.login(user):
            response = self.post(
                "students:grade_task",
                pk=student.id,
                course_task_id=course_task.id,
                data=data,
            )

        self.response_302(response)
        assert (Grade.objects.filter(student=student,
                                     graded_work=graded_work).count() == 1)
Beispiel #6
0
    def test_planned_dates_for_future_school_years(self):
        """The planned dates for a future school year match with the year."""
        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,
        )
        enrollment = EnrollmentFactory(student__school=user.school,
                                       grade_level__school_year=school_year)
        course = CourseFactory(grade_levels=[enrollment.grade_level])
        CourseTaskFactory(course=course)

        with self.login(user):
            self.get_check_200("students:course",
                               uuid=enrollment.student.uuid,
                               course_uuid=course.uuid)

        task_item = self.get_context("task_items")[0]
        assert task_item["planned_date"] == school_year.start_date
Beispiel #7
0
    def test_post(self):
        user = self.make_user()
        grade_level = GradeLevelFactory(school_year__school=user.school)
        course = CourseFactory(grade_levels=[grade_level])
        task = CourseTaskFactory(description="some description",
                                 duration=30,
                                 course=course)
        data = {
            "course": str(task.course.id),
            "description": "new description",
            "duration": 15,
        }

        with self.login(user):
            response = self.post("courses:task_edit",
                                 uuid=task.uuid,
                                 data=data)

        task.refresh_from_db()
        assert task.description == data["description"]
        assert task.duration == data["duration"]
        self.response_302(response)
Beispiel #8
0
    def test_fetch_graded_work(self):
        user = self.make_user()
        student = StudentFactory(school=user.school)
        grade_level = GradeLevelFactory(school_year__school=user.school)
        course = CourseFactory(grade_levels=[grade_level])
        graded_work_1 = GradedWorkFactory(course_task__course=course)
        CourseworkFactory(student=student,
                          course_task=graded_work_1.course_task)
        GradeFactory(student=student, graded_work=graded_work_1)
        graded_work_2 = GradedWorkFactory(course_task__course=course)
        CourseworkFactory(student=student,
                          course_task=graded_work_2.course_task)

        with self.login(user):
            self.get("students:grade")

        assert self.get_context("work_to_grade") == [{
            "student":
            student,
            "graded_work": [graded_work_2]
        }]
        assert self.get_context("has_work_to_grade")
    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),
            student=None,
        )

        assert count == 1
Beispiel #10
0
    def test_post(self):
        user = self.make_user()
        grade_level = GradeLevelFactory(school_year__school=user.school)
        course = CourseFactory(grade_levels=[grade_level])
        data = {
            "course": str(course.id),
            "title": "Charlotte's Web",
            "details": "That's some pig.",
        }

        with self.login(user):
            response = self.post("courses:resource_create",
                                 pk=course.id,
                                 data=data)

        assert CourseResource.objects.count() == 1
        resource = CourseResource.objects.get(course=course)
        assert resource.title == data["title"]
        assert resource.details == data["details"]
        self.response_302(response)
        assert response.get("Location") == self.reverse("courses:detail",
                                                        pk=course.id)
Beispiel #11
0
    def test_future_school_year_advanced_week(self):
        """Looking ahead in a future school year calculates offsets from year start.

        This is slightly different from looking at the first week of a school year
        that has a starting day before the school year starts. The primary functional
        difference is that the future school year will appear in the `schedules`
        context instead of `next_year_schedules` context.
        """
        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),
            # Running only on the last possible day should guarantee 1 task/week.
            days_of_week=SchoolYear.SATURDAY,
        )
        enrollment = EnrollmentFactory(
            grade_level__school_year=school_year, student__school=user.school
        )
        course = CourseFactory(
            grade_levels=[enrollment.grade_level], days_of_week=Course.SATURDAY
        )
        CourseTaskFactory(course=course)
        task = CourseTaskFactory(course=course)
        week = Week(school_year.start_date)
        first_day = week.first_day + datetime.timedelta(days=7)

        with self.login(user):
            self.get(
                "core:weekly",
                year=first_day.year,
                month=first_day.month,
                day=first_day.day,
            )

        schedule = self.get_context("schedules")[0]
        assert schedule["courses"][0]["days"][0]["task"] == task
Beispiel #12
0
    def test_has_tasks_with_completed(self):
        user = self.make_user()
        enrollment = EnrollmentFactory(
            student__school=user.school,
            grade_level__school_year__school=user.school)
        student = enrollment.student
        grade_level = enrollment.grade_level
        course = CourseFactory(grade_levels=[grade_level],
                               days_of_week=Course.WEDNESDAY + Course.THURSDAY)
        task_1 = CourseTaskFactory(course=course)
        coursework = CourseworkFactory(course_task=task_1, student=student)
        task_2 = CourseTaskFactory(course=course)
        GradedWorkFactory(course_task=task_2)
        today = timezone.now().date() + datetime.timedelta(days=2)

        with self.login(user):
            self.get_check_200(
                "students:course",
                uuid=student.uuid,
                course_uuid=course.uuid,
                data={"completed_tasks": "1"},
            )

        self.assertContext(
            "task_items",
            [
                {
                    "course_task": task_1,
                    "coursework": coursework,
                    "has_graded_work": False,
                },
                {
                    "course_task": task_2,
                    "planned_date": today,
                    "has_graded_work": True
                },
            ],
        )
Beispiel #13
0
    def test_get_week_coursework(self):
        today = timezone.now().date()
        week = Week(today)
        enrollment = EnrollmentFactory(
            grade_level__school_year__start_date=today - datetime.timedelta(days=30)
        )
        student = enrollment.student
        school_year = enrollment.grade_level.school_year
        GradeLevelFactory(school_year=school_year)
        course = CourseFactory()
        course.grade_levels.add(enrollment.grade_level)
        coursework_1 = CourseworkFactory(
            student=student, course_task__course=course, completed_date=week.first_day
        )
        coursework_2 = CourseworkFactory(
            student=student, course_task__course=course, completed_date=week.first_day
        )

        week_coursework = student.get_week_coursework(week)

        assert week_coursework == {
            course.id: {week.first_day: [coursework_1, coursework_2]}
        }
Beispiel #14
0
    def test_post(self):
        """A POST creates a coursework."""
        user = self.make_user()
        student = StudentFactory(school=user.school)
        grade_level = GradeLevelFactory(school_year__school=user.school)
        EnrollmentFactory(student=student, grade_level=grade_level)
        course = CourseFactory(grade_levels=[grade_level])
        course_task = CourseTaskFactory(course=course)
        data = {"completed_date": str(grade_level.school_year.start_date)}

        with self.login(user):
            response = self.post(
                "students:coursework",
                pk=student.id,
                course_task_id=course_task.id,
                data=data,
            )

        self.response_302(response)
        assert (
            Coursework.objects.filter(student=student, course_task=course_task).count()
            == 1
        )
Beispiel #15
0
    def test_post(self):
        user = self.make_user()
        grade_level = GradeLevelFactory(school_year__school=user.school)
        course = CourseFactory(grade_levels=[grade_level])
        data = {
            "course": str(course.id),
            "description": "A new task",
            "duration": "30"
        }

        with self.login(user):
            response = self.post("courses:task_create",
                                 uuid=course.uuid,
                                 data=data)

        assert CourseTask.objects.count() == 1
        task = CourseTask.objects.get(course=course)
        assert task.description == data["description"]
        assert task.duration == int(data["duration"])
        self.response_302(response)
        assert response.get("Location") == self.reverse("courses:detail",
                                                        uuid=course.uuid)
        assert not hasattr(task, "graded_work")
Beispiel #16
0
    def test_planned_dates_for_future_school_years(self):
        """The planned dates for a future school year match with the year."""
        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,
        )
        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)
        forecaster = Forecaster()

        items = forecaster.get_task_items(enrollment.student, course)

        task_item = items[0]
        assert task_item["planned_date"] == school_year.start_date
Beispiel #17
0
    def test_no_forecast_course_not_running(self):
        """A course that isn't running will not forecast dates."""
        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,
        )
        enrollment = EnrollmentFactory(student__school=user.school,
                                       grade_level__school_year=school_year)
        course = CourseFactory(grade_levels=[enrollment.grade_level],
                               days_of_week=Course.NO_DAYS)
        CourseTaskFactory(course=course)

        with self.login(user):
            self.get_check_200("students:course",
                               uuid=enrollment.student.uuid,
                               course_uuid=course.uuid)

        task_item = self.get_context("task_items")[0]
        assert "planned_date" not in task_item
Beispiel #18
0
    def test_no_forecast_course_not_running(self):
        """A course that isn't running will not forecast dates."""
        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,
        )
        enrollment = EnrollmentFactory(
            student__school=user.school, grade_level__school_year=school_year
        )
        course = CourseFactory(
            grade_levels=[enrollment.grade_level], days_of_week=Course.NO_DAYS
        )
        CourseTaskFactory(course=course)
        forecaster = Forecaster()

        items = forecaster.get_task_items(enrollment.student, course)

        task_item = items[0]
        assert "planned_date" not in task_item
    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
Beispiel #20
0
    def test_redirect_next(self):
        """After creation, the user returns to the next URL."""
        next_url = "/another/location/"
        user = self.make_user()
        grade_level = GradeLevelFactory(school_year__school=user.school)
        course = CourseFactory(grade_levels=[grade_level])
        data = {
            "form-TOTAL_FORMS": "1",
            "form-INITIAL_FORMS": "0",
            "form-MIN_NUM_FORMS": "0",
            "form-MAX_NUM_FORMS": "1000",
            "form-0-course": str(course.id),
            "form-0-description": "A new task",
            "form-0-duration": "42",
        }
        url = self.reverse("courses:task_create_bulk", pk=course.id)
        url += f"?next={next_url}"

        with self.login(user):
            response = self.post(url, data=data)

        self.response_302(response)
        assert next_url in response.get("Location")
Beispiel #21
0
    def test_school_year_days_superset_of_courses_days(self):
        """The days of a school year must be a superset of each course's days."""
        school = SchoolFactory()
        school_year = SchoolYearFactory(school=school)
        grade_level = GradeLevelFactory(school_year=school_year)
        course = CourseFactory(
            grade_levels=[grade_level], days_of_week=Course.MONDAY + Course.TUESDAY
        )
        data = {
            "school": str(school.id),
            "start_date": "1/1/2020",
            "end_date": "12/31/2020",
            "monday": True,
        }
        form = SchoolYearForm(user=school.admin, instance=school_year, data=data)

        is_valid = form.is_valid()

        assert not is_valid
        assert (
            "The school year days must include any days that a course runs."
            " The following courses run on more days than the school year:"
            f" {course}" in form.non_field_errors()
        )
Beispiel #22
0
    def test_get_week_coursework(self):
        today = timezone.now().date()
        monday = today + relativedelta(weekday=MO(-1))
        sunday = today + relativedelta(weekday=SU(+1))
        week = (monday, sunday)
        enrollment = EnrollmentFactory(
            grade_level__school_year__start_date=today - datetime.timedelta(days=30)
        )
        student = enrollment.student
        school_year = enrollment.grade_level.school_year
        GradeLevelFactory(school_year=school_year)
        course = CourseFactory(grade_level=enrollment.grade_level)
        coursework_1 = CourseworkFactory(
            student=student, course_task__course=course, completed_date=monday
        )
        coursework_2 = CourseworkFactory(
            student=student, course_task__course=course, completed_date=monday
        )

        week_coursework = student.get_week_coursework(week)

        self.assertEqual(
            week_coursework, {course.id: {monday: [coursework_1, coursework_2]}}
        )
Beispiel #23
0
    def test_has_tasks_with_completed(self):
        """Completed tasks appear in the context when the query flag is present."""
        user = self.make_user()
        enrollment = EnrollmentFactory(
            student__school=user.school,
            grade_level__school_year__school=user.school)
        student = enrollment.student
        grade_level = enrollment.grade_level
        course = CourseFactory(grade_levels=[grade_level])
        task_1 = CourseTaskFactory(course=course)
        coursework = CourseworkFactory(course_task=task_1, student=student)
        task_2 = CourseTaskFactory(course=course)
        GradedWorkFactory(course_task=task_2)
        tuesday = timezone.localdate() + datetime.timedelta(days=1)

        with self.login(user):
            self.get_check_200(
                "students:course",
                uuid=student.uuid,
                course_uuid=course.uuid,
                data={"completed_tasks": "1"},
            )

        assert coursework.completed_date == timezone.localdate()
        assert self.get_context("task_items") == [
            {
                "course_task": task_1,
                "coursework": coursework,
                "has_graded_work": False
            },
            {
                "course_task": task_2,
                "planned_date": tuesday,
                "has_graded_work": True
            },
        ]
Beispiel #24
0
    def test_post(self):
        user = self.make_user()
        grade_level = GradeLevelFactory(school_year__school=user.school)
        course = CourseFactory(grade_levels=[grade_level])
        data = {
            "form-TOTAL_FORMS": "1",
            "form-INITIAL_FORMS": "0",
            "form-MIN_NUM_FORMS": "0",
            "form-MAX_NUM_FORMS": "1000",
            "form-0-course": str(course.id),
            "form-0-description": "A new task",
            "form-0-duration": "42",
        }

        with self.login(user):
            response = self.post("courses:task_create_bulk", pk=course.id, data=data)

        assert CourseTask.objects.count() == 1
        task = CourseTask.objects.get(course=course)
        assert task.description == data["form-0-description"]
        assert task.duration == int(data["form-0-duration"])
        self.response_302(response)
        assert response.get("Location") == self.reverse("courses:detail", pk=course.id)
        assert not hasattr(task, "graded_work")
Beispiel #25
0
    def test_has_courses(self):
        grade_level = GradeLevelFactory()
        course = CourseFactory()
        grade_level.courses.add(course)

        assert list(grade_level.courses.all()) == [course]
Beispiel #26
0
 def test_unauthenticated_access(self):
     course = CourseFactory()
     task = CourseTaskFactory(course=course)
     self.assertLoginRequired("courses:task_delete", course_id=course.id, pk=task.id)
Beispiel #27
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]
Beispiel #28
0
 def test_unauthenticated_access(self):
     course = CourseFactory()
     self.assertLoginRequired(
         "courses:task_create_bulk_hx", pk=course.id, last_form_number=42
     )
Beispiel #29
0
 def test_unauthenticated_access(self):
     course = CourseFactory()
     self.assertLoginRequired("courses:delete", pk=course.id)
Beispiel #30
0
 def test_unauthenticated_access(self):
     course = CourseFactory()
     self.assertLoginRequired("courses:task_create_bulk", pk=course.id)