def test_caching_global(self):
        global_config = CourseDurationLimitConfig(enabled=True,
                                                  enabled_as_of=datetime(
                                                      2018,
                                                      1,
                                                      1,
                                                      tzinfo=pytz.UTC))
        global_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the global value is not retrieved from cache after save
        with self.assertNumQueries(1):
            assert CourseDurationLimitConfig.current().enabled

        RequestCache.clear_all_namespaces()

        # Check that the global value can be retrieved from cache after read
        with self.assertNumQueries(0):
            assert CourseDurationLimitConfig.current().enabled

        global_config.enabled = False
        global_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the global value in cache was deleted on save
        with self.assertNumQueries(1):
            assert not CourseDurationLimitConfig.current().enabled
示例#2
0
    def test_caching_course(self):
        course = CourseOverviewFactory.create(org='test-org')
        site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': course.org})
        course_config = CourseDurationLimitConfig(course=course, enabled=True, enabled_as_of=datetime(2018, 1, 1))
        course_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value is not retrieved from cache after save
        with self.assertNumQueries(2):
            self.assertTrue(CourseDurationLimitConfig.current(course_key=course.id).enabled)

        RequestCache.clear_all_namespaces()

        # Check that the org value can be retrieved from cache after read
        with self.assertNumQueries(0):
            self.assertTrue(CourseDurationLimitConfig.current(course_key=course.id).enabled)

        course_config.enabled = False
        course_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value in cache was deleted on save
        with self.assertNumQueries(2):
            self.assertFalse(CourseDurationLimitConfig.current(course_key=course.id).enabled)

        global_config = CourseDurationLimitConfig(enabled=True, enabled_as_of=datetime(2018, 1, 1))
        global_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value is not updated in cache by changing the global value
        with self.assertNumQueries(0):
            self.assertFalse(CourseDurationLimitConfig.current(course_key=course.id).enabled)

        site_config = CourseDurationLimitConfig(site=site_cfg.site, enabled=True, enabled_as_of=datetime(2018, 1, 1))
        site_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value is not updated in cache by changing the site value
        with self.assertNumQueries(0):
            self.assertFalse(CourseDurationLimitConfig.current(course_key=course.id).enabled)

        org_config = CourseDurationLimitConfig(org=course.org, enabled=True, enabled_as_of=datetime(2018, 1, 1))
        org_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value is not updated in cache by changing the site value
        with self.assertNumQueries(0):
            self.assertFalse(CourseDurationLimitConfig.current(course_key=course.id).enabled)
示例#3
0
    def test_caching_course(self):
        course = CourseOverviewFactory.create(org='test-org')
        site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': course.org})
        course_config = CourseDurationLimitConfig(course=course, enabled=True, enabled_as_of=datetime(2018, 1, 1))
        course_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value is not retrieved from cache after save
        with self.assertNumQueries(2):
            self.assertTrue(CourseDurationLimitConfig.current(course_key=course.id).enabled)

        RequestCache.clear_all_namespaces()

        # Check that the org value can be retrieved from cache after read
        with self.assertNumQueries(0):
            self.assertTrue(CourseDurationLimitConfig.current(course_key=course.id).enabled)

        course_config.enabled = False
        course_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value in cache was deleted on save
        with self.assertNumQueries(2):
            self.assertFalse(CourseDurationLimitConfig.current(course_key=course.id).enabled)

        global_config = CourseDurationLimitConfig(enabled=True, enabled_as_of=datetime(2018, 1, 1))
        global_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value is not updated in cache by changing the global value
        with self.assertNumQueries(0):
            self.assertFalse(CourseDurationLimitConfig.current(course_key=course.id).enabled)

        site_config = CourseDurationLimitConfig(site=site_cfg.site, enabled=True, enabled_as_of=datetime(2018, 1, 1))
        site_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value is not updated in cache by changing the site value
        with self.assertNumQueries(0):
            self.assertFalse(CourseDurationLimitConfig.current(course_key=course.id).enabled)

        org_config = CourseDurationLimitConfig(org=course.org, enabled=True, enabled_as_of=datetime(2018, 1, 1))
        org_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value is not updated in cache by changing the site value
        with self.assertNumQueries(0):
            self.assertFalse(CourseDurationLimitConfig.current(course_key=course.id).enabled)
 def test_course_messaging_for_staff(self):
     """
     Staff users will not see the expiration banner when course duration limits
     are on for the course.
     """
     config = CourseDurationLimitConfig(course=CourseOverview.get_from_id(
         self.course.id),
                                        enabled=True,
                                        enabled_as_of=datetime(2018, 1, 1))
     config.save()
     url = course_home_url(self.course)
     CourseEnrollment.enroll(self.staff_user, self.course.id)
     response = self.client.get(url)
     bannerText = get_expiration_banner_text(self.staff_user, self.course)
     self.assertNotContains(response, bannerText, html=True)
示例#5
0
 def test_course_messaging_for_staff(self):
     """
     Staff users will not see the expiration banner when course duration limits
     are on for the course.
     """
     config = CourseDurationLimitConfig(
         course=CourseOverview.get_from_id(self.course.id),
         enabled=True,
         enabled_as_of=datetime(2018, 1, 1)
     )
     config.save()
     url = course_home_url(self.course)
     CourseEnrollment.enroll(self.staff_user, self.course.id)
     response = self.client.get(url)
     bannerText = get_expiration_banner_text(self.staff_user, self.course)
     self.assertNotContains(response, bannerText, html=True)
示例#6
0
    def test_caching_global(self):
        global_config = CourseDurationLimitConfig(enabled=True, enabled_as_of=date(2018, 1, 1))
        global_config.save()

        # Check that the global value is not retrieved from cache after save
        with self.assertNumQueries(1):
            self.assertTrue(CourseDurationLimitConfig.current().enabled)

        # Check that the global value can be retrieved from cache after read
        with self.assertNumQueries(0):
            self.assertTrue(CourseDurationLimitConfig.current().enabled)

        global_config.enabled = False
        global_config.save()

        # Check that the global value in cache was deleted on save
        with self.assertNumQueries(1):
            self.assertFalse(CourseDurationLimitConfig.current().enabled)
示例#7
0
    def test_caching_global(self):
        global_config = CourseDurationLimitConfig(enabled=True, enabled_as_of=datetime(2018, 1, 1))
        global_config.save()

        # Check that the global value is not retrieved from cache after save
        with self.assertNumQueries(1):
            self.assertTrue(CourseDurationLimitConfig.current().enabled)

        # Check that the global value can be retrieved from cache after read
        with self.assertNumQueries(0):
            self.assertTrue(CourseDurationLimitConfig.current().enabled)

        global_config.enabled = False
        global_config.save()

        # Check that the global value in cache was deleted on save
        with self.assertNumQueries(1):
            self.assertFalse(CourseDurationLimitConfig.current().enabled)
    def test_caching_org(self):
        course = CourseOverviewFactory.create(org='test-org')
        site_cfg = SiteConfigurationFactory.create(
            site_values={'course_org_filter': course.org})
        org_config = CourseDurationLimitConfig(org=course.org, enabled=True, enabled_as_of=datetime(2018, 1, 1, tzinfo=pytz.UTC))  # lint-amnesty, pylint: disable=line-too-long
        org_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value is not retrieved from cache after save
        with self.assertNumQueries(2):
            assert CourseDurationLimitConfig.current(org=course.org).enabled

        RequestCache.clear_all_namespaces()

        # Check that the org value can be retrieved from cache after read
        with self.assertNumQueries(0):
            assert CourseDurationLimitConfig.current(org=course.org).enabled

        org_config.enabled = False
        org_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value in cache was deleted on save
        with self.assertNumQueries(2):
            assert not CourseDurationLimitConfig.current(
                org=course.org).enabled

        global_config = CourseDurationLimitConfig(enabled=True,
                                                  enabled_as_of=datetime(
                                                      2018,
                                                      1,
                                                      1,
                                                      tzinfo=pytz.UTC))
        global_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value is not updated in cache by changing the global value
        with self.assertNumQueries(0):
            assert not CourseDurationLimitConfig.current(
                org=course.org).enabled

        site_config = CourseDurationLimitConfig(site=site_cfg.site, enabled=True, enabled_as_of=datetime(2018, 1, 1, tzinfo=pytz.UTC))  # lint-amnesty, pylint: disable=line-too-long
        site_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the org value is not updated in cache by changing the site value
        with self.assertNumQueries(0):
            assert not CourseDurationLimitConfig.current(
                org=course.org).enabled
示例#9
0
    def test_course_expiration_banner_with_unicode(self,
                                                   mock_strftime_localized,
                                                   mock_get_date_string):
        """
        Ensure that switching to other languages that have unicode in their
        date representations will not cause the course home page to 404.
        """
        fake_unicode_start_time = u"üñîçø∂é_ßtå®t_tîµé"
        mock_strftime_localized.return_value = fake_unicode_start_time
        date_string = u'<span class="localized-datetime" data-format="shortDate" \
        data-datetime="{formatted_date}" data-language="{language}">{formatted_date_localized}</span>'

        mock_get_date_string.return_value = date_string

        config = CourseDurationLimitConfig(course=CourseOverview.get_from_id(
            self.course.id),
                                           enabled=True,
                                           enabled_as_of=datetime(2018,
                                                                  1,
                                                                  1,
                                                                  tzinfo=UTC))
        config.save()
        url = course_home_url(self.course)
        user = self.create_user_for_course(self.course,
                                           CourseUserType.UNENROLLED)
        CourseEnrollment.enroll(user, self.course.id)

        language = 'eo'
        DarkLangConfig(released_languages=language,
                       changed_by=user,
                       enabled=True).save()

        response = self.client.get(url, HTTP_ACCEPT_LANGUAGE=language)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response['Content-Language'], language)

        # Check that if the string is incorrectly not marked as unicode we still get the error
        with mock.patch(
                "openedx.features.course_duration_limits.access.get_date_string",
                return_value=date_string.encode('utf-8')):
            response = self.client.get(url, HTTP_ACCEPT_LANGUAGE=language)
            self.assertEqual(response.status_code, 500)
示例#10
0
    def test_caching_site(self):
        site_cfg = SiteConfigurationFactory()
        site_config = CourseDurationLimitConfig(site=site_cfg.site,
                                                enabled=True,
                                                enabled_as_of=datetime(
                                                    2018, 1, 1))
        site_config.save()

        # Check that the site value is not retrieved from cache after save
        with self.assertNumQueries(1):
            self.assertTrue(
                CourseDurationLimitConfig.current(site=site_cfg.site).enabled)

        # Check that the site value can be retrieved from cache after read
        with self.assertNumQueries(0):
            self.assertTrue(
                CourseDurationLimitConfig.current(site=site_cfg.site).enabled)

        site_config.enabled = False
        site_config.save()

        # Check that the site value in cache was deleted on save
        with self.assertNumQueries(1):
            self.assertFalse(
                CourseDurationLimitConfig.current(site=site_cfg.site).enabled)

        global_config = CourseDurationLimitConfig(enabled=True,
                                                  enabled_as_of=datetime(
                                                      2018, 1, 1))
        global_config.save()

        # Check that the site value is not updated in cache by changing the global value
        with self.assertNumQueries(0):
            self.assertFalse(
                CourseDurationLimitConfig.current(site=site_cfg.site).enabled)
示例#11
0
    def test_caching_site(self):
        site_cfg = SiteConfigurationFactory()
        site_config = CourseDurationLimitConfig(site=site_cfg.site, enabled=True, enabled_as_of=datetime(2018, 1, 1))
        site_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the site value is not retrieved from cache after save
        with self.assertNumQueries(1):
            self.assertTrue(CourseDurationLimitConfig.current(site=site_cfg.site).enabled)

        RequestCache.clear_all_namespaces()

        # Check that the site value can be retrieved from cache after read
        with self.assertNumQueries(0):
            self.assertTrue(CourseDurationLimitConfig.current(site=site_cfg.site).enabled)

        site_config.enabled = False
        site_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the site value in cache was deleted on save
        with self.assertNumQueries(1):
            self.assertFalse(CourseDurationLimitConfig.current(site=site_cfg.site).enabled)

        global_config = CourseDurationLimitConfig(enabled=True, enabled_as_of=datetime(2018, 1, 1))
        global_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the site value is not updated in cache by changing the global value
        with self.assertNumQueries(0):
            self.assertFalse(CourseDurationLimitConfig.current(site=site_cfg.site).enabled)
示例#12
0
    def test_course_expiration_banner_with_unicode(self, mock_strftime_localized, mock_get_date_string):
        """
        Ensure that switching to other languages that have unicode in their
        date representations will not cause the course home page to 404.
        """
        fake_unicode_start_time = u"üñîçø∂é_ßtå®t_tîµé"
        mock_strftime_localized.return_value = fake_unicode_start_time
        date_string = u'<span class="localized-datetime" data-format="shortDate" \
        data-datetime="{formatted_date}" data-language="{language}">{formatted_date_localized}</span>'
        mock_get_date_string.return_value = date_string

        config = CourseDurationLimitConfig(
            course=CourseOverview.get_from_id(self.course.id),
            enabled=True,
            enabled_as_of=datetime(2018, 1, 1)
        )
        config.save()
        url = course_home_url(self.course)
        user = self.create_user_for_course(self.course, CourseUserType.UNENROLLED)
        CourseEnrollment.enroll(user, self.course.id)

        language = 'eo'
        DarkLangConfig(
            released_languages=language,
            changed_by=user,
            enabled=True
        ).save()

        response = self.client.get(url, HTTP_ACCEPT_LANGUAGE=language)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response['Content-Language'], language)

        # Check that if the string is incorrectly not marked as unicode we still get the error
        with mock.patch("openedx.features.course_duration_limits.access.get_date_string",
                        return_value=date_string.encode('utf-8')):
            response = self.client.get(url, HTTP_ACCEPT_LANGUAGE=language)
            self.assertEqual(response.status_code, 500)
    def test_caching_site(self):
        site_cfg = SiteConfigurationFactory()
        site_config = CourseDurationLimitConfig(site=site_cfg.site, enabled=True, enabled_as_of=datetime(2018, 1, 1, tzinfo=pytz.UTC))  # lint-amnesty, pylint: disable=line-too-long
        site_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the site value is not retrieved from cache after save
        with self.assertNumQueries(1):
            assert CourseDurationLimitConfig.current(
                site=site_cfg.site).enabled

        RequestCache.clear_all_namespaces()

        # Check that the site value can be retrieved from cache after read
        with self.assertNumQueries(0):
            assert CourseDurationLimitConfig.current(
                site=site_cfg.site).enabled

        site_config.enabled = False
        site_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the site value in cache was deleted on save
        with self.assertNumQueries(1):
            assert not CourseDurationLimitConfig.current(
                site=site_cfg.site).enabled

        global_config = CourseDurationLimitConfig(enabled=True,
                                                  enabled_as_of=datetime(
                                                      2018,
                                                      1,
                                                      1,
                                                      tzinfo=pytz.UTC))
        global_config.save()

        RequestCache.clear_all_namespaces()

        # Check that the site value is not updated in cache by changing the global value
        with self.assertNumQueries(0):
            assert not CourseDurationLimitConfig.current(
                site=site_cfg.site).enabled
    def test_course_messaging(self):
        """
        Ensure that the following four use cases work as expected

        1) Anonymous users are shown a course message linking them to the login page
        2) Unenrolled users are shown a course message allowing them to enroll
        3) Enrolled users who show up on the course page after the course has begun
        are not shown a course message.
        4) Enrolled users who show up on the course page after the course has begun will
        see the course expiration banner if course duration limits are on for the course.
        5) Enrolled users who show up on the course page before the course begins
        are shown a message explaining when the course starts as well as a call to
        action button that allows them to add a calendar event.
        """
        # Verify that anonymous users are shown a login link in the course message
        url = course_home_url(self.course)
        response = self.client.get(url)
        self.assertContains(response, TEST_COURSE_HOME_MESSAGE)
        self.assertContains(response, TEST_COURSE_HOME_MESSAGE_ANONYMOUS)

        # Verify that unenrolled users are shown an enroll call to action message
        user = self.create_user_for_course(self.course,
                                           CourseUserType.UNENROLLED)
        url = course_home_url(self.course)
        response = self.client.get(url)
        self.assertContains(response, TEST_COURSE_HOME_MESSAGE)
        self.assertContains(response, TEST_COURSE_HOME_MESSAGE_UNENROLLED)

        # Verify that enrolled users are not shown any state warning message when enrolled and course has begun.
        CourseEnrollment.enroll(user, self.course.id)
        url = course_home_url(self.course)
        response = self.client.get(url)
        self.assertNotContains(response, TEST_COURSE_HOME_MESSAGE_ANONYMOUS)
        self.assertNotContains(response, TEST_COURSE_HOME_MESSAGE_UNENROLLED)
        self.assertNotContains(response, TEST_COURSE_HOME_MESSAGE_PRE_START)

        # Verify that enrolled users are shown the course expiration banner if content gating is enabled

        # We use .save() explicitly here (rather than .objects.create) in order to force the
        # cache to refresh.
        config = CourseDurationLimitConfig(course=CourseOverview.get_from_id(
            self.course.id),
                                           enabled=True,
                                           enabled_as_of=datetime(2018, 1, 1))
        config.save()

        url = course_home_url(self.course)
        response = self.client.get(url)
        bannerText = get_expiration_banner_text(user, self.course)
        self.assertContains(response, bannerText, html=True)

        # Verify that enrolled users are not shown the course expiration banner if content gating is disabled
        config.enabled = False
        config.save()
        url = course_home_url(self.course)
        response = self.client.get(url)
        bannerText = get_expiration_banner_text(user, self.course)
        self.assertNotContains(response, bannerText, html=True)

        # Verify that enrolled users are shown 'days until start' message before start date
        future_course = self.create_future_course()
        CourseEnrollment.enroll(user, future_course.id)
        url = course_home_url(future_course)
        response = self.client.get(url)
        self.assertContains(response, TEST_COURSE_HOME_MESSAGE)
        self.assertContains(response, TEST_COURSE_HOME_MESSAGE_PRE_START)
示例#15
0
    def test_course_messaging(self):
        """
        Ensure that the following four use cases work as expected

        1) Anonymous users are shown a course message linking them to the login page
        2) Unenrolled users are shown a course message allowing them to enroll
        3) Enrolled users who show up on the course page after the course has begun
        are not shown a course message.
        4) Enrolled users who show up on the course page after the course has begun will
        see the course expiration banner if course duration limits are on for the course.
        5) Enrolled users who show up on the course page before the course begins
        are shown a message explaining when the course starts as well as a call to
        action button that allows them to add a calendar event.
        """
        # Verify that anonymous users are shown a login link in the course message
        url = course_home_url(self.course)
        response = self.client.get(url)
        self.assertContains(response, TEST_COURSE_HOME_MESSAGE)
        self.assertContains(response, TEST_COURSE_HOME_MESSAGE_ANONYMOUS)

        # Verify that unenrolled users are shown an enroll call to action message
        user = self.create_user_for_course(self.course, CourseUserType.UNENROLLED)
        url = course_home_url(self.course)
        response = self.client.get(url)
        self.assertContains(response, TEST_COURSE_HOME_MESSAGE)
        self.assertContains(response, TEST_COURSE_HOME_MESSAGE_UNENROLLED)

        # Verify that enrolled users are not shown any state warning message when enrolled and course has begun.
        CourseEnrollment.enroll(user, self.course.id)
        url = course_home_url(self.course)
        response = self.client.get(url)
        self.assertNotContains(response, TEST_COURSE_HOME_MESSAGE_ANONYMOUS)
        self.assertNotContains(response, TEST_COURSE_HOME_MESSAGE_UNENROLLED)
        self.assertNotContains(response, TEST_COURSE_HOME_MESSAGE_PRE_START)

        # Verify that enrolled users are shown the course expiration banner if content gating is enabled

        # We use .save() explicitly here (rather than .objects.create) in order to force the
        # cache to refresh.
        config = CourseDurationLimitConfig(
            course=CourseOverview.get_from_id(self.course.id),
            enabled=True,
            enabled_as_of=datetime(2018, 1, 1)
        )
        config.save()

        url = course_home_url(self.course)
        response = self.client.get(url)
        bannerText = get_expiration_banner_text(user, self.course)
        self.assertContains(response, bannerText, html=True)
        self.assertContains(response, TEST_BANNER_CLASS)

        # Verify that enrolled users are not shown the course expiration banner if content gating is disabled
        config.enabled = False
        config.save()
        url = course_home_url(self.course)
        response = self.client.get(url)
        bannerText = get_expiration_banner_text(user, self.course)
        self.assertNotContains(response, bannerText, html=True)

        # Verify that enrolled users are shown 'days until start' message before start date
        future_course = self.create_future_course()
        CourseEnrollment.enroll(user, future_course.id)
        url = course_home_url(future_course)
        response = self.client.get(url)
        self.assertContains(response, TEST_COURSE_HOME_MESSAGE)
        self.assertContains(response, TEST_COURSE_HOME_MESSAGE_PRE_START)