From 3b928e3e99113af1c717b28b9d14f43e0a8b6f0e Mon Sep 17 00:00:00 2001
From: Michael LoTurco <mikeloturco13@gmail.com>
Date: Wed, 28 Feb 2018 14:24:06 -0500
Subject: [PATCH] Adds EntitlementSupportView, Template, and base react element

---
 .../static/support/jsx/entitlements/index.jsx |  9 +++
 lms/djangoapps/support/tests/test_views.py    | 79 -------------------
 lms/djangoapps/support/urls.py                | 12 +--
 .../support/views/course_entitlements.py      | 25 +++++-
 lms/templates/support/entitlement.html        | 34 ++++++++
 package-lock.json                             | 13 ++-
 package.json                                  |  4 +-
 webpack.common.config.js                      |  1 +
 8 files changed, 78 insertions(+), 99 deletions(-)
 create mode 100644 lms/djangoapps/support/static/support/jsx/entitlements/index.jsx
 create mode 100644 lms/templates/support/entitlement.html

diff --git a/lms/djangoapps/support/static/support/jsx/entitlements/index.jsx b/lms/djangoapps/support/static/support/jsx/entitlements/index.jsx
new file mode 100644
index 00000000000..ce5b7487ccb
--- /dev/null
+++ b/lms/djangoapps/support/static/support/jsx/entitlements/index.jsx
@@ -0,0 +1,9 @@
+import React from 'react';
+
+const EntitlementSupportPage = () => (
+  <div>
+    Base Entitlement Support Page
+  </div>
+);
+
+export default EntitlementSupportPage;
diff --git a/lms/djangoapps/support/tests/test_views.py b/lms/djangoapps/support/tests/test_views.py
index 32b8489ad95..9e853c90814 100644
--- a/lms/djangoapps/support/tests/test_views.py
+++ b/lms/djangoapps/support/tests/test_views.py
@@ -437,82 +437,3 @@ class SupportViewEnrollmentsTests(SharedModuleStoreTestCase, SupportViewTestCase
         )
         verified_mode.expiration_datetime = datetime(year=1970, month=1, day=9, tzinfo=UTC)
         verified_mode.save()
-
-
-@ddt.ddt
-class SupportViewCourseEntitlementsTests(SupportViewTestCase):
-    """ Tests for the course entitlement support view."""
-
-    def setUp(self):
-        super(SupportViewCourseEntitlementsTests, self).setUp()
-        self.user = UserFactory(is_staff=True)
-        SupportStaffRole().add_users(self.user)
-        self.client.login(username=self.user.username, password=TEST_PASSWORD)
-
-        self.student = UserFactory.create(username='student', email='test@example.com', password='test')
-        self.course_uuid = uuid4()
-
-        self.url = reverse('support:course_entitlement')
-
-    @ddt.data('username', 'email')
-    def test_get_entitlements(self, search_string_type):
-        CourseEntitlementFactory.create(mode=CourseMode.VERIFIED, user=self.student, course_uuid=self.course_uuid)
-        url = self.url + getattr(self.student, search_string_type)
-        response = self.client.get(url)
-        self.assertEqual(response.status_code, 200)
-        data = json.loads(response.content)
-        self.assertEqual(len(data), 1)
-        self.assertDictContainsSubset({
-            'user': self.student.username,
-            'course_uuid': unicode(self.course_uuid),
-            'enrollment_course_run': None,
-            'mode': CourseMode.VERIFIED,
-            'support_details': []
-        }, data[0])
-
-    def test_reinstate_entitlement(self):
-        selected_run = CourseEnrollmentFactory(mode=CourseMode.VERIFIED, user=self.student)
-        expired_entitlement = CourseEntitlementFactory.create(
-            mode=CourseMode.VERIFIED, user=self.student, enrollment_course_run=selected_run, expired_at=datetime.now()
-        )
-        url = self.url + self.student.username
-        response = self.client.put(url, data=json.dumps(
-            {
-                'entitlement_uuid': unicode(expired_entitlement.uuid),
-                'reason': CourseEntitlementSupportDetail.LEAVE_SESSION
-            }),
-            content_type='application/json'
-        )
-        self.assertEqual(response.status_code, 200)
-        data = json.loads(response.content)
-        self.assertEqual(len(data['support_details']), 1)
-        self.assertDictContainsSubset({
-            'support_user': self.user.username,
-            'reason': CourseEntitlementSupportDetail.LEAVE_SESSION,
-            'comments': None,
-            'unenrolled_run': unicode(selected_run.course_id)
-        }, data['support_details'][0])
-
-    def test_create_entitlement(self):
-        CourseEntitlementFactory.create(
-            mode=CourseMode.VERIFIED, user=self.student, course_uuid=self.course_uuid, expired_at=datetime.now()
-        )
-        url = self.url + self.student.username
-        response = self.client.post(
-            url,
-            data=json.dumps({
-                'course_uuid': unicode(self.course_uuid),
-                'reason': CourseEntitlementSupportDetail.LEARNER_REQUEST_NEW,
-                'mode': CourseMode.VERIFIED
-            }),
-            content_type='application/json',
-        )
-        self.assertEqual(response.status_code, 201)
-        data = json.loads(response.content)
-        self.assertEqual(len(data['support_details']), 1)
-        self.assertDictContainsSubset({
-            'support_user': self.user.username,
-            'reason': CourseEntitlementSupportDetail.LEARNER_REQUEST_NEW,
-            'comments': None,
-            'unenrolled_run': None
-        }, data['support_details'][0])
diff --git a/lms/djangoapps/support/urls.py b/lms/djangoapps/support/urls.py
index 1bd324d23a6..494bfcb1a4c 100644
--- a/lms/djangoapps/support/urls.py
+++ b/lms/djangoapps/support/urls.py
@@ -11,21 +11,13 @@ from support.views.index import index
 from support.views.manage_user import ManageUserDetailView, ManageUserSupportView
 from support.views.refund import RefundSupportView
 
-COURSE_ENTITLEMENTS_VIEW = EntitlementSupportView.as_view({
-    'get': 'list',
-    'post': 'create',
-    'put': 'update'
-})
+COURSE_ENTITLEMENTS_VIEW = EntitlementSupportView.as_view()
 
 urlpatterns = [
     url(r'^$', index, name="index"),
     url(r'^certificates/?$', CertificatesSupportView.as_view(), name="certificates"),
     url(r'^refund/?$', RefundSupportView.as_view(), name="refund"),
-    url(
-        r'^course_entitlement/(?P<username_or_email>[\w.@+-]+)?$',
-        COURSE_ENTITLEMENTS_VIEW,
-        name="course_entitlement"
-    ),
+    url(r'^course_entitlement/?$', COURSE_ENTITLEMENTS_VIEW, name="course_entitlement"),
     url(r'^enrollment/?$', EnrollmentSupportView.as_view(), name="enrollment"),
     url(r'^contact_us/?$', ContactUsView.as_view(), name="contact_us"),
     url(
diff --git a/lms/djangoapps/support/views/course_entitlements.py b/lms/djangoapps/support/views/course_entitlements.py
index 79d64fdced2..6a93c964641 100644
--- a/lms/djangoapps/support/views/course_entitlements.py
+++ b/lms/djangoapps/support/views/course_entitlements.py
@@ -6,20 +6,43 @@ from django.db import DatabaseError, transaction
 from django.db.models import Q
 from django.http import HttpResponseBadRequest
 from django.utils.decorators import method_decorator
+from django.views.generic import View
 from edx_rest_framework_extensions.authentication import JwtAuthentication
 from rest_framework import permissions, status, viewsets
 from rest_framework.response import Response
 
+from edxmako.shortcuts import render_to_response
 from entitlements.api.v1.permissions import IsAdminOrAuthenticatedReadOnly
 from entitlements.api.v1.serializers import SupportCourseEntitlementSerializer
 from entitlements.models import CourseEntitlement, CourseEntitlementSupportDetail
+from lms.djangoapps.commerce.utils import EcommerceService
 from lms.djangoapps.support.decorators import require_support_permission
 from openedx.core.djangoapps.cors_csrf.authentication import SessionAuthenticationCrossDomainCsrf
 
 REQUIRED_CREATION_FIELDS = ['course_uuid', 'reason', 'mode']
 
 
-class EntitlementSupportView(viewsets.ModelViewSet):
+class EntitlementSupportView(View):
+    """
+    View for viewing and changing learner enrollments, used by the
+    support team.
+    """
+    @method_decorator(require_support_permission)
+    def get(self, request):
+        """Render the enrollment support tool view."""
+        support_actions = CourseEntitlementSupportDetail.get_support_actions_list()
+
+        ecommerce_url = EcommerceService().get_order_dashboard_url()
+        context = {
+            'username': request.GET.get('user', ''),
+            'uses_bootstrap': True,
+            'ecommerce_url': ecommerce_url,
+            'support_actions': support_actions
+        }
+        return render_to_response('support/entitlement.html', context)
+
+
+class EntitlementSupportListView(viewsets.ModelViewSet):
     """
     Allows viewing and changing learner course entitlements, used the support team.
     """
diff --git a/lms/templates/support/entitlement.html b/lms/templates/support/entitlement.html
new file mode 100644
index 00000000000..f193160f4c0
--- /dev/null
+++ b/lms/templates/support/entitlement.html
@@ -0,0 +1,34 @@
+<%page expression_filter="h"/>
+
+<%!
+from django.utils.translation import ugettext as _
+from openedx.core.djangolib.js_utils import js_escaped_string
+%>
+
+## Override the default styles_version to use Bootstrap
+<%! main_css = "css/bootstrap/lms-main.css" %>
+
+<%namespace name='static' file='../static_content.html'/>
+
+<%inherit file="../main.html" />
+
+<%block name="js_extra">
+</%block>
+
+<%block name="pagetitle">
+	${_("Entitlements")}
+</%block>
+
+<%block name="content">
+	<section class="container outside-app">
+	  ${static.renderReact(
+	      component="EntitlementSupportPage",
+	      id="entitlement-support-page",
+	      props={
+	      	'ecommerceUrl': ecommerce_url, 
+	      	'supportReasons': support_actions
+	      }
+	    )
+	  }
+	</section>
+</%block>
diff --git a/package-lock.json b/package-lock.json
index 06fd3ea6672..43d52557cc6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7981,11 +7981,10 @@
       "integrity": "sha1-eHTi04kR0nGeoncx0yRF2l7EOUw="
     },
     "react": {
-      "version": "15.6.2",
-      "resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz",
-      "integrity": "sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=",
+      "version": "16.1.0",
+      "resolved": "https://registry.npmjs.org/react/-/react-16.1.0.tgz",
+      "integrity": "sha512-hvKYlKqde2JNnNiEzORvSA0J1L7uSZ43l+J89ZNoP4EXxQrVNH0CFj8vorfPou3w+1ou1BNMBir2VVsuXtETRA==",
       "requires": {
-        "create-react-class": "15.6.3",
         "fbjs": "0.8.16",
         "loose-envify": "1.3.1",
         "object-assign": "4.1.1",
@@ -8003,9 +8002,9 @@
       }
     },
     "react-dom": {
-      "version": "15.6.2",
-      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.6.2.tgz",
-      "integrity": "sha1-Qc+t9pO3V/rycIRDodH9WgK+9zA=",
+      "version": "16.1.0",
+      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.1.0.tgz",
+      "integrity": "sha512-i9in5qW3H2PDinUPD9bnQK7tLAD8LhjYQ+fXi3nJOvVnxOO3ErHq6RNEnKY7pbjTPt155e74q7al8eBUuyLtew==",
       "requires": {
         "fbjs": "0.8.16",
         "loose-envify": "1.3.1",
diff --git a/package.json b/package.json
index c6d2a49b730..9030300d23b 100644
--- a/package.json
+++ b/package.json
@@ -40,8 +40,8 @@
     "popper.js": "1.12.9",
     "prop-types": "15.6.0",
     "raw-loader": "0.5.1",
-    "react": "15.6.2",
-    "react-dom": "15.6.2",
+    "react": "16.1.0",
+    "react-dom": "16.1.0",
     "react-slick": "0.16.0",
     "requirejs": "2.3.5",
     "rtlcss": "2.2.1",
diff --git a/webpack.common.config.js b/webpack.common.config.js
index 31c0cc1bd83..2c71829b2cf 100644
--- a/webpack.common.config.js
+++ b/webpack.common.config.js
@@ -29,6 +29,7 @@ module.exports = {
         LearnerAnalyticsDashboard: './lms/static/js/learner_analytics_dashboard/LearnerAnalyticsDashboard.jsx',
         UpsellExperimentModal: './lms/static/common/js/components/UpsellExperimentModal.jsx',
         PortfolioExperimentUpsellModal: './lms/static/common/js/components/PortfolioExperimentUpsellModal.jsx',
+        EntitlementSupportPage: './lms/djangoapps/support/static/support/jsx/entitlements/index.jsx',
 
         // Learner Dashboard
         EntitlementFactory: './lms/static/js/learner_dashboard/course_entitlement_factory.js',
-- 
GitLab