From 5f5a44e062d8c97445fd9816af9ee8b9c351f87e Mon Sep 17 00:00:00 2001
From: Matt Drayer <mattdrayer@edx.org>
Date: Mon, 15 May 2017 14:44:12 -0400
Subject: [PATCH] Hide the audit option from track selection for certain
 enterprise use cases

---
 common/djangoapps/course_modes/models.py      |  3 +
 .../course_modes/tests/test_views.py          | 72 +++++++++++--------
 common/djangoapps/course_modes/views.py       | 11 ++-
 .../tests/mixins/enterprise.py                |  4 +-
 4 files changed, 57 insertions(+), 33 deletions(-)

diff --git a/common/djangoapps/course_modes/models.py b/common/djangoapps/course_modes/models.py
index e33ee372229..ad29d2d4a82 100644
--- a/common/djangoapps/course_modes/models.py
+++ b/common/djangoapps/course_modes/models.py
@@ -122,6 +122,9 @@ class CourseMode(models.Model):
     DEFAULT_MODE = Mode(AUDIT, _('Audit'), 0, '', 'usd', None, None, None, None)
     DEFAULT_MODE_SLUG = AUDIT
 
+    # Modes utilized for audit/free enrollments
+    AUDIT_MODES = [AUDIT, HONOR]
+
     # Modes that allow a student to pursue a verified certificate
     VERIFIED_MODES = [VERIFIED, PROFESSIONAL]
 
diff --git a/common/djangoapps/course_modes/tests/test_views.py b/common/djangoapps/course_modes/tests/test_views.py
index efcf0e5ac79..b60edc050e5 100644
--- a/common/djangoapps/course_modes/tests/test_views.py
+++ b/common/djangoapps/course_modes/tests/test_views.py
@@ -133,18 +133,28 @@ class CourseModeViewTest(CatalogIntegrationMixin, UrlResetMixin, ModuleStoreTest
         self.assertRedirects(response, 'http://testserver/test_basket/?sku=TEST', fetch_redirect_response=False)
         ecomm_test_utils.update_commerce_config(enabled=False)
 
-    @httpretty.activate
-    def test_no_enrollment(self):
+    def _generate_enterprise_learner_context(self, enable_audit_enrollment=False):
+        """
+        Internal helper to support common pieces of test case variations
+        """
         # Create the course modes
         for mode in ('audit', 'honor', 'verified'):
             CourseModeFactory.create(mode_slug=mode, course_id=self.course.id)
 
-        self.mock_enterprise_learner_api()
+        catalog_integration = self.create_catalog_integration()
+        UserFactory(username=catalog_integration.service_username)
 
-        # User visits the track selection page directly without ever enrolling
-        url = reverse('course_modes_choose', args=[unicode(self.course.id)])
-        response = self.client.get(url)
+        self.mock_course_discovery_api_for_catalog_contains(
+            catalog_id=1, course_run_ids=[str(self.course.id)]
+        )
+        self.mock_enterprise_learner_api(enable_audit_enrollment=enable_audit_enrollment)
+
+        return reverse('course_modes_choose', args=[unicode(self.course.id)])
 
+    @httpretty.activate
+    def test_no_enrollment(self):
+        url = self._generate_enterprise_learner_context()
+        response = self.client.get(url)
         self.assertEquals(response.status_code, 200)
 
     @httpretty.activate
@@ -152,21 +162,9 @@ class CourseModeViewTest(CatalogIntegrationMixin, UrlResetMixin, ModuleStoreTest
         """
         Test: Track selection page should show the enterprise context message if user belongs to the Enterprise.
         """
-        # Create the course modes
-        for mode in ('audit', 'honor', 'verified'):
-            CourseModeFactory.create(mode_slug=mode, course_id=self.course.id)
-
-        catalog_integration = self.create_catalog_integration()
-        UserFactory(username=catalog_integration.service_username)
-
-        self.mock_enterprise_learner_api()
-
-        self.mock_course_discovery_api_for_catalog_contains(
-            catalog_id=1, course_run_ids=[str(self.course.id)]
-        )
+        url = self._generate_enterprise_learner_context()
 
         # User visits the track selection page directly without ever enrolling
-        url = reverse('course_modes_choose', args=[unicode(self.course.id)])
         response = self.client.get(url)
         self.assertEquals(response.status_code, 200)
         self.assertContains(
@@ -185,16 +183,7 @@ class CourseModeViewTest(CatalogIntegrationMixin, UrlResetMixin, ModuleStoreTest
         Test: Track selection page should show the enterprise context message with multiple organization names
         if user belongs to the Enterprise.
         """
-        # Create the course modes
-        for mode in ('audit', 'honor', 'verified'):
-            CourseModeFactory.create(mode_slug=mode, course_id=self.course.id)
-
-        catalog_integration = self.create_catalog_integration()
-        UserFactory(username=catalog_integration.service_username)
-        self.mock_enterprise_learner_api()
-        self.mock_course_discovery_api_for_catalog_contains(
-            catalog_id=1, course_run_ids=[str(self.course.id)]
-        )
+        url = self._generate_enterprise_learner_context()
 
         # Creating organization
         for i in xrange(2):
@@ -209,7 +198,6 @@ class CourseModeViewTest(CatalogIntegrationMixin, UrlResetMixin, ModuleStoreTest
             organizations_api.add_organization_course(organization_data=test_org, course_id=unicode(self.course.id))
 
         # User visits the track selection page directly without ever enrolling
-        url = reverse('course_modes_choose', args=[unicode(self.course.id)])
         response = self.client.get(url)
         self.assertEquals(response.status_code, 200)
         self.assertContains(
@@ -221,6 +209,30 @@ class CourseModeViewTest(CatalogIntegrationMixin, UrlResetMixin, ModuleStoreTest
             )
         )
 
+    @httpretty.activate
+    def test_enterprise_learner_context_audit_disabled(self):
+        """
+        Track selection page should hide the audit choice by default in an Enterprise Customer/Learner context
+        """
+
+        # User visits the track selection page directly without ever enrolling, sees only Verified track choice
+        url = self._generate_enterprise_learner_context()
+        response = self.client.get(url)
+        self.assertContains(response, 'Pursue a Verified Certificate')
+        self.assertNotContains(response, 'Audit This Course')
+
+    @httpretty.activate
+    def test_enterprise_learner_context_audit_enabled(self):
+        """
+        Track selection page should display Audit choice when specified for an Enterprise Customer
+        """
+
+        # User visits the track selection page directly without ever enrolling, sees both Verified and Audit choices
+        url = self._generate_enterprise_learner_context(enable_audit_enrollment=True)
+        response = self.client.get(url)
+        self.assertContains(response, 'Pursue a Verified Certificate')
+        self.assertContains(response, 'Audit This Course')
+
     @httpretty.activate
     @ddt.data(
         '',
diff --git a/common/djangoapps/course_modes/views.py b/common/djangoapps/course_modes/views.py
index 9377021f08f..69bf5a08e8b 100644
--- a/common/djangoapps/course_modes/views.py
+++ b/common/djangoapps/course_modes/views.py
@@ -156,16 +156,17 @@ class ChooseModeView(View):
         )
         enterprise_learner_data = enterprise_api.get_enterprise_learner_data(site=request.site, user=request.user)
         if enterprise_learner_data:
+            enterprise_learner = enterprise_learner_data[0]
             is_course_in_enterprise_catalog = enterprise_api.is_course_in_enterprise_catalog(
                 site=request.site,
                 course_id=course_id,
-                enterprise_catalog_id=enterprise_learner_data[0]['enterprise_customer']['catalog']
+                enterprise_catalog_id=enterprise_learner['enterprise_customer']['catalog']
             )
 
             if is_course_in_enterprise_catalog:
                 partner_names = partner_name = course.display_organization \
                     if course.display_organization else course.org
-                enterprise_name = enterprise_learner_data[0]['enterprise_customer']['name']
+                enterprise_name = enterprise_learner['enterprise_customer']['name']
                 organizations = organization_api.get_course_organizations(course_id=course.id)
                 if organizations:
                     partner_names = ' and '.join([org.get('name', partner_name) for org in organizations])
@@ -178,6 +179,12 @@ class ChooseModeView(View):
                     partner_names=partner_names,
                     enterprise_name=enterprise_name
                 )
+
+                # Hide the audit modes for this enterprise customer, if necessary
+                if not enterprise_learner['enterprise_customer'].get('enable_audit_enrollment'):
+                    for audit_mode in CourseMode.AUDIT_MODES:
+                        modes.pop(audit_mode, None)
+
         context["title_content"] = title_content
 
         if "verified" in modes:
diff --git a/openedx/features/enterprise_support/tests/mixins/enterprise.py b/openedx/features/enterprise_support/tests/mixins/enterprise.py
index 2df604186d1..5415d73e28b 100644
--- a/openedx/features/enterprise_support/tests/mixins/enterprise.py
+++ b/openedx/features/enterprise_support/tests/mixins/enterprise.py
@@ -62,7 +62,8 @@ class EnterpriseServiceMockMixin(object):
             catalog_id=1,
             entitlement_id=1,
             learner_id=1,
-            enterprise_customer_uuid='cf246b88-d5f6-4908-a522-fc307e0b0c59'
+            enterprise_customer_uuid='cf246b88-d5f6-4908-a522-fc307e0b0c59',
+            enable_audit_enrollment=False,
     ):
         """
         Helper function to register enterprise learner API endpoint.
@@ -85,6 +86,7 @@ class EnterpriseServiceMockMixin(object):
                         },
                         'enable_data_sharing_consent': True,
                         'enforce_data_sharing_consent': 'at_login',
+                        'enable_audit_enrollment': enable_audit_enrollment,
                         'enterprise_customer_users': [
                             1
                         ],
-- 
GitLab