diff --git a/common/djangoapps/course_modes/views.py b/common/djangoapps/course_modes/views.py index e7351a1da2..655f1378d2 100644 --- a/common/djangoapps/course_modes/views.py +++ b/common/djangoapps/course_modes/views.py @@ -31,6 +31,7 @@ from openedx.core.djangoapps.embargo import api as embargo_api from openedx.core.djangoapps.programs.utils import ProgramDataExtender, ProgramProgressMeter from openedx.core.djangoapps.waffle_utils import WaffleFlag, WaffleFlagNamespace from openedx.features.content_type_gating.models import ContentTypeGatingConfig +from openedx.features.course_duration_limits.models import CourseDurationLimitConfig from student.models import CourseEnrollment from util.db import outer_atomic from xmodule.modulestore.django import modulestore @@ -192,6 +193,10 @@ class ChooseModeView(View): user=request.user, course_key=course_key ), + "course_duration_limit_enabled": CourseDurationLimitConfig.enabled_for_enrollment( + user=request.user, + course_key=course_key + ), } context.update( get_experiment_user_metadata_context( diff --git a/lms/templates/course_modes/choose.html b/lms/templates/course_modes/choose.html index 068b89919b..7859ab228b 100644 --- a/lms/templates/course_modes/choose.html +++ b/lms/templates/course_modes/choose.html @@ -86,7 +86,7 @@ from openedx.core.djangolib.markup import HTML, Text
${Text(_("Audit this course for free and have access to course materials and discussions forums. {b_start}This track does not include graded assignments, or unlimited course access.{b_end}")).format(**b_tag_kwargs)}
+ % elif content_gating_enabled and not course_duration_limit_enabled: +${Text(_("Audit this course for free and have access to course materials and discussions forums. {b_start}This track does not include graded assignments.{b_end}")).format(**b_tag_kwargs)}
+ % elif not content_gating_enabled and course_duration_limit_enabled: +${Text(_("Audit this course for free and have access to course materials and discussions forums. {b_start}This track does not include unlimited course access.{b_end}")).format(**b_tag_kwargs)}
% else:${Text(_("Audit this course for free and have complete access to all the course material, activities, tests, and forums. {b_start}Please note that this track does not offer a certificate for learners who earn a passing grade.{b_end}")).format(**b_tag_kwargs)}
% endif diff --git a/openedx/core/djangoapps/config_model_utils/utils.py b/openedx/core/djangoapps/config_model_utils/utils.py new file mode 100644 index 0000000000..eae11e1814 --- /dev/null +++ b/openedx/core/djangoapps/config_model_utils/utils.py @@ -0,0 +1,25 @@ +"""utils for feature-based enrollments""" +from experiments.models import ExperimentData +from openedx.features.course_duration_limits.config import ( + EXPERIMENT_ID, + EXPERIMENT_DATA_HOLDBACK_KEY +) + + +def is_in_holdback(user): + """ + Return true if given user is in holdback expermiment + """ + in_holdback = False + if user and user.is_authenticated: + try: + holdback_value = ExperimentData.objects.get( + user=user, + experiment_id=EXPERIMENT_ID, + key=EXPERIMENT_DATA_HOLDBACK_KEY, + ).value + in_holdback = holdback_value == 'True' + except ExperimentData.DoesNotExist: + pass + + return in_holdback diff --git a/openedx/features/content_type_gating/models.py b/openedx/features/content_type_gating/models.py index c608a670f1..17e97dace1 100644 --- a/openedx/features/content_type_gating/models.py +++ b/openedx/features/content_type_gating/models.py @@ -12,14 +12,12 @@ from django.utils.translation import ugettext_lazy as _ from django.utils import timezone from lms.djangoapps.courseware.masquerade import get_course_masquerade, is_masquerading_as_specific_student -from experiments.models import ExperimentData from openedx.core.djangoapps.config_model_utils.models import StackedConfigurationModel +from openedx.core.djangoapps.config_model_utils.utils import is_in_holdback from openedx.features.content_type_gating.helpers import has_staff_roles from openedx.features.course_duration_limits.config import ( CONTENT_TYPE_GATING_FLAG, FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG, - EXPERIMENT_ID, - EXPERIMENT_DATA_HOLDBACK_KEY ) from student.models import CourseEnrollment @@ -109,18 +107,7 @@ class ContentTypeGatingConfig(StackedConfigurationModel): return False # check if user is in holdback - is_in_holdback = False - if user and user.is_authenticated and (user_variable_represents_correct_user): - try: - holdback_value = ExperimentData.objects.get( - user=user, - experiment_id=EXPERIMENT_ID, - key=EXPERIMENT_DATA_HOLDBACK_KEY, - ).value - is_in_holdback = holdback_value == 'True' - except ExperimentData.DoesNotExist: - pass - if is_in_holdback: + if user_variable_represents_correct_user and is_in_holdback(user): return False # enrollment might be None if the user isn't enrolled. In that case, diff --git a/openedx/features/course_duration_limits/models.py b/openedx/features/course_duration_limits/models.py index 7f8f76a550..783c632dd1 100644 --- a/openedx/features/course_duration_limits/models.py +++ b/openedx/features/course_duration_limits/models.py @@ -13,20 +13,18 @@ from django.utils.translation import ugettext_lazy as _ from django.utils import timezone from course_modes.models import CourseMode -from experiments.models import ExperimentData from lms.djangoapps.courseware.masquerade import ( get_course_masquerade, get_masquerade_role, is_masquerading_as_specific_student ) from openedx.core.djangoapps.config_model_utils.models import StackedConfigurationModel +from openedx.core.djangoapps.config_model_utils.utils import is_in_holdback from openedx.features.content_type_gating.helpers import has_staff_roles from openedx.features.content_type_gating.partitions import CONTENT_GATING_PARTITION_ID, CONTENT_TYPE_GATE_GROUP_IDS from openedx.features.course_duration_limits.config import ( CONTENT_TYPE_GATING_FLAG, FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG, - EXPERIMENT_ID, - EXPERIMENT_DATA_HOLDBACK_KEY ) from student.models import CourseEnrollment from xmodule.partitions.partitions import ENROLLMENT_TRACK_PARTITION_ID @@ -130,20 +128,10 @@ class CourseDurationLimitConfig(StackedConfigurationModel): return False no_masquerade = get_course_masquerade(user, course_key) is None - is_in_holdback = False student_masquerade = is_masquerading_as_specific_student(user, course_key) - # TODO: clean up as part of REV-100 - if user and user.username and (no_masquerade or student_masquerade): - try: - holdback_value = ExperimentData.objects.get( - user=user, - experiment_id=EXPERIMENT_ID, - key=EXPERIMENT_DATA_HOLDBACK_KEY, - ).value - is_in_holdback = holdback_value == 'True' - except ExperimentData.DoesNotExist: - pass - if is_in_holdback: + + # check if user is in holdback + if (no_masquerade or student_masquerade) and is_in_holdback(user): return False # enrollment might be None if the user isn't enrolled. In that case, diff --git a/openedx/features/course_duration_limits/tests/test_models.py b/openedx/features/course_duration_limits/tests/test_models.py index 723c0dedda..6a6db087cd 100644 --- a/openedx/features/course_duration_limits/tests/test_models.py +++ b/openedx/features/course_duration_limits/tests/test_models.py @@ -80,9 +80,9 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase): user = self.user course_key = self.course_overview.id - query_count = 8 - if not pass_enrollment: - query_count = 9 + query_count = 9 + if pass_enrollment and already_enrolled: + query_count = 8 with self.assertNumQueries(query_count): enabled = CourseDurationLimitConfig.enabled_for_enrollment( diff --git a/themes/edx.org/lms/templates/course_modes/choose.html b/themes/edx.org/lms/templates/course_modes/choose.html index 3b82606259..7cf8349647 100644 --- a/themes/edx.org/lms/templates/course_modes/choose.html +++ b/themes/edx.org/lms/templates/course_modes/choose.html @@ -154,7 +154,7 @@ from openedx.features.portfolio_project import INCLUDE_PORTFOLIO_UPSELL_MODAL
${Text(_("Audit this course for free and have access to course materials and discussions forums. {b_start}This track does not include graded assignments, or unlimited course access.{b_end}")).format(**b_tag_kwargs)}
+ % elif content_gating_enabled and not course_duration_limit_enabled: +${Text(_("Audit this course for free and have access to course materials and discussions forums. {b_start}This track does not include graded assignments.{b_end}")).format(**b_tag_kwargs)}
+ % elif not content_gating_enabled and course_duration_limit_enabled: +${Text(_("Audit this course for free and have access to course materials and discussions forums. {b_start}This track does not include unlimited course access.{b_end}")).format(**b_tag_kwargs)}
% else:${Text(_("Audit this course for free and have complete access to all the course material, activities, tests, and forums. {b_start}Please note that this track does not offer a certificate for learners who earn a passing grade.{b_end}")).format(**b_tag_kwargs)}
% endif