Пример #1
0
 def test_models_course_state_coming_soon(self):
     """
     Confirm course state result when there is no course runs at all.
     """
     course = CourseFactory()
     with self.assertNumQueries(3):
         state = course.state
     self.assertEqual(state, CourseState(6))
Пример #2
0
 def test_models_course_state_archived(self):
     """
     Confirm course state when there is a course run only in the past.
     """
     course = CourseFactory()
     self.create_run_archived(course)
     with self.assertNumQueries(2):
         state = course.state
     self.assertEqual(state, CourseState(5))
Пример #3
0
 def test_templates_course_run_detail_state_with_cta(self):
     """A course run in a state with a call to action should include a link and the CTA."""
     response = self.prepare_to_test_state(CourseState(0, timezone.now()))
     self.assertContains(
         response,
         '<a class="subheader__cta" '
         'href="https://www.example.com/enroll">Enroll now</a>',
         html=True,
     )
 def test_models_course_state_archived_open(self):
     """
     Confirm course state when there is a past course run but open for enrollment.
     """
     course = CourseFactory()
     course_run = self.create_run_archived_open(course)
     with self.assertNumQueries(3):
         state = course.state
     self.assertEqual(state, CourseState(2, course_run.enrollment_end))
 def test_templates_course_detail_state_with_cta(self):
     """A course run in a state with a call to action should include a link and the CTA."""
     response = self.prepare_to_test_state(CourseState(0, timezone.now()))
     self.assertContains(
         response,
         '<a class="course-detail__aside__run__block__cta" '
         'href="/en/my-course/my-course-run/">Enroll now</a>',
         html=True,
     )
Пример #6
0
 def test_templates_course_run_detail_state_without_cta(self):
     """A course run in a state without a call to action should include a state button."""
     response = self.prepare_to_test_state(CourseState(6))
     self.assertContains(
         response,
         '<button class="subheader__cta '
         'subheader__cta--projected">To be scheduled</button>',
         html=True,
     )
 def test_templates_course_detail_state_without_cta(self):
     """A course run in a state without a call to action should include a state button."""
     response = self.prepare_to_test_state(CourseState(6))
     self.assertContains(
         response,
         '<a class="course-detail__aside__run__block__cta '
         'course-detail__aside__run__block__cta--projected" '
         'href="/en/my-course/my-course-run/">To be scheduled</a>',
         html=True,
     )
Пример #8
0
 def test_models_course_state_ongoing_enrollment_closed(self):
     """
     Confirm course state when there is an on-going course run but closed for
     enrollment.
     """
     course = CourseFactory()
     self.create_run_ongoing_closed(course)
     with self.assertNumQueries(2):
         state = course.state
     self.assertEqual(state, CourseState(4))
Пример #9
0
 def test_models_course_run_state_ongoing_closed(self):
     """
     A course run that is on-going but closed for enrollment should return a state with
     "on-going" as text and no CTA.
     """
     course_run = CourseRunFactory(
         enrollment_start=self.now - timedelta(hours=3),
         start=self.now - timedelta(hours=2),
         enrollment_end=self.now - timedelta(hours=1),
         end=self.now + timedelta(hours=1),
     )
     self.assertEqual(course_run.state, CourseState(4, None, "on-going", None))
Пример #10
0
 def test_models_course_run_state_future_closed(self):
     """
     A course run that is future and already closed for enrollment should return a state
     with "enrollment closed" as text and no CTA.
     """
     course_run = CourseRunFactory(
         enrollment_start=self.now - timedelta(hours=2),
         enrollment_end=self.now - timedelta(hours=1),
         start=self.now + timedelta(hours=1),
         end=self.now + timedelta(hours=2),
     )
     self.assertEqual(
         course_run.state, CourseState(3, None, "enrollment closed", None)
     )
Пример #11
0
 def test_indexers_courses_format_es_object_for_api_no_organization(self):
     """
     A course that has no organization and was indexed should not raise 500 errors (although
     this should not happen if courses are correctly moderated).
     """
     es_course = {
         "_id": 93,
         "_source": {
             "absolute_url": {"en": "campo-qui-format-do"},
             "categories": [43, 86],
             "code": "abc123",
             "cover_image": {"en": "cover_image.jpg"},
             "duration": {"en": "3 weeks"},
             "effort": {"en": "10 minutes"},
             "icon": {"en": "icon.jpg"},
             "introduction": {"en": "introductio est"},
             "organization_highlighted": None,
             "organization_highlighted_cover_image": {},
             "organizations": [],
             "organizations_names": {},
             "title": {"en": "Duis eu arcu erat"},
         },
         "fields": {
             "state": [
                 {"priority": 0, "date_time": "2019-03-17T21:25:52.179667+00:00"}
             ]
         },
     }
     self.assertEqual(
         CoursesIndexer.format_es_object_for_api(es_course, "en"),
         {
             "id": 93,
             "absolute_url": "campo-qui-format-do",
             "categories": [43, 86],
             "code": "abc123",
             "cover_image": "cover_image.jpg",
             "duration": "3 weeks",
             "effort": "10 minutes",
             "icon": "icon.jpg",
             "introduction": "introductio est",
             "organization_highlighted": None,
             "organization_highlighted_cover_image": None,
             "organizations": [],
             "title": "Duis eu arcu erat",
             "state": CourseState(
                 0, datetime(2019, 3, 17, 21, 25, 52, 179667, pytz.utc)
             ),
         },
     )
 def test_templates_course_run_detail_state_without_cta(self):
     """A course run in a state without a call to action should include a state button."""
     response = self.prepare_to_test_state(
         CourseState(
             random.randint(0, 6),
             None,
             "state text",
             random.choice([datetime.now(), None]),
         ))
     self.assertContains(
         response,
         '<button class="course-detail__content__run__block__cta '
         'course-detail__content__run__block__cta--projected">State text</button>',
         html=True,
     )
 def test_templates_course_run_detail_state_with_cta(self):
     """A course run in a state with a call to action should include a link and the CTA."""
     response = self.prepare_to_test_state(
         CourseState(
             random.randint(0, 6),
             "state cta",
             random.choice(["state text", None]),
             random.choice([datetime.now(), None]),
         ))
     self.assertContains(
         response,
         '<a class="course-detail__content__run__block__cta" '
         'href="https://www.example.com/enroll">State cta</a>',
         html=True,
     )
Пример #14
0
 def test_models_course_run_state_coming(self):
     """
     A course run that is future and not yet open for enrollment should return a state
     with a CTA to see details with the start date.
     """
     course_run = CourseRunFactory(
         enrollment_start=self.now + timedelta(hours=1),
         enrollment_end=self.now + timedelta(hours=2),
         start=self.now + timedelta(hours=3),
         end=self.now + timedelta(hours=4),
     )
     self.assertEqual(
         course_run.state,
         CourseState(2, "see details", "starting on", course_run.start),
     )
Пример #15
0
 def test_models_course_run_state_ongoing_open(self):
     """
     A course run that is on-going and open for enrollment should return a state with a CTA
     to enroll and the date of the end of enrollment.
     """
     course_run = CourseRunFactory(
         enrollment_start=self.now - timedelta(hours=3),
         start=self.now - timedelta(hours=2),
         enrollment_end=self.now + timedelta(hours=1),
         end=self.now + timedelta(hours=2),
     )
     self.assertEqual(
         course_run.state,
         CourseState(0, "enroll now", "closing on", course_run.enrollment_end),
     )
Пример #16
0
 def test_templates_course_run_detail_state_with_enrollments_app_without_cta(
         self):
     """A course run in a state without a call to action just calls the frontend component."""
     response, course_run = self.prepare_to_test_state(
         CourseState(6, timezone.now()),
         resource_link=
         "http://edx:8073/courses/course-v1:edX+DemoX+Demo/course/",
     )
     self.assertIsNotNone(
         re.search(
             (r'.*class="richie-react richie-react--course-run-enrollment".*'
              r"data-props=\\\'{{\"courseRunId\": {}}}\\\'".format(
                  course_run.public_extension_id)),
             str(response.content),
         ))
Пример #17
0
 def test_models_course_run_state_future_open(self):
     """
     A course run that is future and open for enrollment should return a state with a CTA
     to enroll and the start date.
     """
     course_run = CourseRunFactory(
         enrollment_start=self.now - timedelta(hours=1),
         enrollment_end=self.now + timedelta(hours=1),
         start=self.now + timedelta(hours=2),
         end=self.now + timedelta(hours=3),
     )
     self.assertEqual(
         course_run.state,
         CourseState(1, "enroll now", "starting on", course_run.start),
     )
Пример #18
0
 def test_indexers_courses_format_es_object_for_api_no_cover(self):
     """
     A course that has no cover image and was indexed should not raise any errors.
     """
     es_course = {
         "_id": 93,
         "_source": {
             "absolute_url": {"en": "campo-qui-format-do"},
             "categories": [43, 86],
             "code": "abc123",
             "cover_image": {},
             "duration": {"en": "N/A"},
             "effort": {"en": "N/A"},
             "icon": {"en": "icon.jpg"},
             "introduction": {"en": "introductio est"},
             "organization_highlighted": {"en": "Org 42"},
             "organization_highlighted_cover_image": {},
             "organizations": [42, 84],
             "organizations_names": {"en": ["Org 42", "Org 84"]},
             "title": {"en": "Duis eu arcu erat"},
         },
         "fields": {
             "state": [
                 {"priority": 0, "date_time": "2019-03-17T21:25:52.179667+00:00"}
             ]
         },
     }
     self.assertEqual(
         CoursesIndexer.format_es_object_for_api(es_course, "en"),
         {
             "id": 93,
             "absolute_url": "campo-qui-format-do",
             "categories": [43, 86],
             "code": "abc123",
             "cover_image": None,
             "duration": "N/A",
             "effort": "N/A",
             "icon": "icon.jpg",
             "introduction": "introductio est",
             "organization_highlighted": "Org 42",
             "organization_highlighted_cover_image": None,
             "organizations": [42, 84],
             "title": "Duis eu arcu erat",
             "state": CourseState(
                 0, datetime(2019, 3, 17, 21, 25, 52, 179667, pytz.utc)
             ),
         },
     )
Пример #19
0
 def test_indexers_courses_format_es_object_for_api(self):
     """
     Make sure format_es_object_for_api returns a properly formatted course
     """
     es_course = {
         "_id": 93,
         "_source": {
             "absolute_url": {"en": "campo-qui-format-do"},
             "categories": [43, 86],
             "code": "abc123",
             "cover_image": {"en": "cover_image.jpg"},
             "duration": {"en": "6 months"},
             "effort": {"en": "3 hours"},
             "icon": {"en": "icon.jpg"},
             "introduction": {"en": "introductio est"},
             "organization_highlighted": {"en": "Org 84"},
             "organization_highlighted_cover_image": {"en": "org_cover_image.jpg"},
             "organizations": [42, 84],
             "organizations_names": {"en": ["Org 42", "Org 84"]},
             "title": {"en": "Duis eu arcu erat"},
         },
         "fields": {
             "state": [
                 {"priority": 0, "date_time": "2019-03-17T21:25:52.179667+00:00"}
             ]
         },
     }
     self.assertEqual(
         CoursesIndexer.format_es_object_for_api(es_course, "en"),
         {
             "id": 93,
             "absolute_url": "campo-qui-format-do",
             "categories": [43, 86],
             "code": "abc123",
             "cover_image": "cover_image.jpg",
             "duration": "6 months",
             "effort": "3 hours",
             "icon": "icon.jpg",
             "introduction": "introductio est",
             "organization_highlighted": "Org 84",
             "organization_highlighted_cover_image": "org_cover_image.jpg",
             "organizations": [42, 84],
             "title": "Duis eu arcu erat",
             "state": CourseState(
                 0, datetime(2019, 3, 17, 21, 25, 52, 179667, pytz.utc)
             ),
         },
     )
Пример #20
0
    def test_models_course_state_future_enrollment_closed(self):
        """
        Confirm course state when there is a future course run but closed for
        enrollment.
        """
        course = CourseFactory()
        self.create_run_future_closed(course)
        with self.assertNumQueries(2):
            state = course.state
        expected_state = CourseState(3)
        self.assertEqual(state, expected_state)

        # Adding an on-going but closed course run should not change the result
        self.create_run_ongoing_closed(course)
        with self.assertNumQueries(2):
            state = course.state
        self.assertEqual(state, expected_state)
Пример #21
0
    def test_models_course_state_future_enrollment_open(self):
        """
        Confirm course state when there is a future course run open for enrollment.
        """
        course = CourseFactory()
        course_run = self.create_run_future_open(course)
        with self.assertNumQueries(2):
            state = course.state
        expected_state = CourseState(1, course_run.start)
        self.assertEqual(state, expected_state)

        # Adding courses in less priorietary states should not change the result
        self.create_run_ongoing_closed(course)
        self.create_run_future_closed(course)
        with self.assertNumQueries(2):
            state = course.state
        self.assertEqual(state, expected_state)
Пример #22
0
    def test_models_course_state_future_enrollment_not_yet_open(self):
        """
        Confirm course state when there is a future course run but not yet open for
        enrollment.
        """
        course = CourseFactory()
        course_run = self.create_run_future_not_yet_open(course)
        with self.assertNumQueries(2):
            state = course.state
        expected_state = CourseState(2, course_run.start)
        self.assertEqual(state, expected_state)

        # Adding an on-going but closed course run should not change the result and require
        # only 1 additional database query
        self.create_run_ongoing_closed(course)
        with self.assertNumQueries(1):
            state = course.state
        self.assertEqual(state, expected_state)
Пример #23
0
    def test_models_course_state_future_enrollment_open(self):
        """
        Confirm course state when there is a future course run open for enrollment.
        """
        course = CourseFactory()
        course_run = self.create_run_future_open(course)
        with self.assertNumQueries(3):
            state = course.state
        expected_state = CourseState(1, course_run.start)
        self.assertEqual(state, expected_state)

        # Adding course runs of lower priority states should not change the result and require
        # only 1 additional database query
        self.create_run_ongoing_closed(course)
        self.create_run_future_closed(course)
        with self.assertNumQueries(1):
            state = course.state
        self.assertEqual(state, expected_state)
Пример #24
0
    def test_models_course_state_ongoing_open(self):
        """
        Confirm course state when there is an on-going course run open for enrollment.
        """
        course = CourseFactory()
        course_run = CourseRunFactory(
            page_parent=course.extended_object,
            start=self.now - timedelta(hours=1),
            end=self.now + timedelta(hours=2),
            enrollment_end=self.now + timedelta(hours=1),
        )
        with self.assertNumQueries(2):
            state = course.state
        expected_state = CourseState(0, course_run.enrollment_end)
        self.assertEqual(state, expected_state)

        # Adding courses in less priorietary states should not change the result
        self.create_run_ongoing_closed(course)
        self.create_run_future_closed(course)
        self.create_run_future_open(course)
        with self.assertNumQueries(2):
            state = course.state
        self.assertEqual(state, expected_state)
Пример #25
0
 def test_models_course_run_state_archived(self):
     """A course run that is passed should return a state with "archived" as text."""
     course_run = CourseRunFactory(
         start=self.now - timedelta(hours=2), end=self.now - timedelta(hours=1)
     )
     self.assertEqual(course_run.state, CourseState(5, None, "archived", None))