Commit 8f5ba011 by asadiqbal Committed by Ayesha Baig

WL-606

parent c7ff473e
......@@ -272,6 +272,7 @@ def create_mode(request, course_id):
`min_price` (int): The minimum price a user must pay to enroll in the new course mode
`suggested_prices` (str): Comma-separated prices to suggest to the user.
`currency` (str): The currency in which to list prices.
`sku` (str): The product SKU value.
By default, this endpoint will create an 'honor' mode for the given course with display name
'Honor Code', a minimum price of 0, no suggested prices, and using USD as the currency.
......@@ -289,6 +290,7 @@ def create_mode(request, course_id):
'min_price': 0,
'suggested_prices': u'',
'currency': u'usd',
'sku': None,
}
# Try pulling querystring parameters out of the request
......
......@@ -14,7 +14,8 @@ class ModeCreationPage(PageObject):
created for an existing course.
"""
def __init__(self, browser, course_id, mode_slug=None, mode_display_name=None, min_price=None, suggested_prices=None, currency=None):
def __init__(self, browser, course_id, mode_slug=None, mode_display_name=None, min_price=None,
suggested_prices=None, currency=None, sku=None):
"""The mode creation page is an endpoint for HTTP GET requests.
By default, it will create an 'honor' mode for the given course with display name
......@@ -30,6 +31,7 @@ class ModeCreationPage(PageObject):
min_price (int): The minimum price a user must pay to enroll in the new course mode
suggested_prices (str): Comma-separated prices to suggest to the user.
currency (str): The currency in which to list prices.
sku (str): The product SKU value.
"""
super(ModeCreationPage, self).__init__(browser)
......@@ -51,6 +53,9 @@ class ModeCreationPage(PageObject):
if currency is not None:
self._parameters['currency'] = currency
if sku is not None:
self._parameters['sku'] = sku
@property
def url(self):
"""Construct the mode creation URL."""
......
......@@ -92,6 +92,15 @@ class InstructorDashboardPage(CoursePage):
email_section.wait_for_page()
return email_section
def select_ecommerce_tab(self):
"""
Selects the E-commerce tab and returns an EcommercePage.
"""
self.q(css='[data-section="e-commerce"]').first.click()
ecommerce_section = EcommercePage(self.browser)
ecommerce_section.wait_for_page()
return ecommerce_section
@staticmethod
def get_asset_path(file_name):
"""
......@@ -1416,3 +1425,19 @@ class CertificatesPage(PageObject):
Returns the message (error/success) in "Certificate Invalidation" section.
"""
return self.get_selector('.certificate-invalidation-container div.message')
class EcommercePage(PageObject):
"""
E-commerce section of the Instructor dashboard.
"""
url = None
def is_browser_on_page(self):
return self.q(css='[data-section="e-commerce"].active-section').present
def get_sections_header_values(self):
"""
Returns a list of the headings text under div.
"""
return self.q(css="div.wrap h3").text
......@@ -1202,3 +1202,112 @@ class CertificateInvalidationTest(BaseInstructorDashboardTest):
'.certificates-wrapper'
])
self.certificates_section.a11y_audit.check_for_accessibility_errors()
@attr(shard=10)
class EcommerceTest(BaseInstructorDashboardTest):
"""
Bok Choy tests for the "E-Commerce" tab.
"""
def setUp(self):
super(EcommerceTest, self).setUp()
def setup_course(self, course_number):
"""
Sets up the course
"""
self.course_info['number'] = course_number
course_fixture = CourseFixture(
self.course_info["org"],
self.course_info["number"],
self.course_info["run"],
self.course_info["display_name"]
)
course_fixture.install()
def log_in_as_unique_user(self):
"""
Log in as a valid lms user.
"""
AutoAuthPage(
self.browser,
username="test_instructor",
email="test_instructor@example.com",
password="password",
course_id=self.course_id
).visit()
def visit_ecommerce_section(self):
"""
Log in to visit Instructor dashboard and click E-commerce tab
"""
self.log_in_as_unique_user()
instructor_dashboard_page = self.visit_instructor_dashboard()
return instructor_dashboard_page.select_ecommerce_tab()
def add_course_mode(self, sku_value=None):
"""
Add an honor mode to the course
"""
ModeCreationPage(browser=self.browser, course_id=self.course_id, mode_slug=u'honor', min_price=10,
sku=sku_value).visit()
def test_enrollment_codes_section_visible_for_non_ecommerce_course(self):
"""
Test Enrollment Codes UI, under E-commerce Tab, should be visible in the Instructor Dashboard with non
e-commerce course
"""
# Setup course
non_ecommerce_course_number = "34039497242734583224814321005482849780"
self.setup_course(non_ecommerce_course_number)
# Add an honor mode to the course
self.add_course_mode()
# Log in and visit E-commerce section under Instructor dashboard
self.assertIn(u'Enrollment Codes', self.visit_ecommerce_section().get_sections_header_values())
def test_coupon_codes_section_visible_for_non_ecommerce_course(self):
"""
Test Coupon Codes UI, under E-commerce Tab, should be visible in the Instructor Dashboard with non
e-commerce course
"""
# Setup course
non_ecommerce_course_number = "34039497242734583224814321005482849781"
self.setup_course(non_ecommerce_course_number)
# Add an honor mode to the course
self.add_course_mode()
# Log in and visit E-commerce section under Instructor dashboard
self.assertIn(u'Coupon Code List', self.visit_ecommerce_section().get_sections_header_values())
def test_enrollment_codes_section_not_visible_for_ecommerce_course(self):
"""
Test Enrollment Codes UI, under E-commerce Tab, should not be visible in the Instructor Dashboard with
e-commerce course
"""
# Setup course
ecommerce_course_number = "34039497242734583224814321005482849782"
self.setup_course(ecommerce_course_number)
# Add an honor mode to the course with sku value
self.add_course_mode('test_sku')
# Log in and visit E-commerce section under Instructor dashboard
self.assertNotIn(u'Enrollment Codes', self.visit_ecommerce_section().get_sections_header_values())
def test_coupon_codes_section_not_visible_for_ecommerce_course(self):
"""
Test Coupon Codes UI, under E-commerce Tab, should not be visible in the Instructor Dashboard with
e-commerce course
"""
# Setup course
ecommerce_course_number = "34039497242734583224814321005482849783"
self.setup_course(ecommerce_course_number)
# Add an honor mode to the course with sku value
self.add_course_mode('test_sku')
# Log in and visit E-commerce section under Instructor dashboard
self.assertNotIn(u'Coupon Code List', self.visit_ecommerce_section().get_sections_header_values())
[
{
"pk": 1,
"model": "auth.user",
"fields": {
"username": "test_instructor",
"email":"test_instructor@example.com",
"password": "password",
"is_staff": true,
"is_active": true
}
},
{
"pk": 1,
"model": "student.userprofile",
"fields": {
"user": 1,
"name": "test instructor",
"courseware": "course.xml"
}
},
{
"pk": 1,
"model": "student.registration",
"fields": {
"user": 1,
"activation_key": "52bfac10384d49219385dcd4cc17177q"
}
},
{
"pk": 1,
"model": "student.courseaccessrole",
"fields": {
"id": "1",
"org": "test_org",
"course_id": "course-v1:test_org+34039497242734583224814321005482849780+test_run",
"role": "finance_admin",
"user_id": "1"
}
},
{
"pk": 2,
"model": "student.courseaccessrole",
"fields": {
"id": "2",
"org": "test_org",
"course_id": "course-v1:test_org+34039497242734583224814321005482849781+test_run",
"role": "finance_admin",
"user_id": "1"
}
},
{
"pk": 3,
"model": "student.courseaccessrole",
"fields": {
"id": "3",
"org": "test_org",
"course_id": "course-v1:test_org+34039497242734583224814321005482849782+test_run",
"role": "finance_admin",
"user_id": "1"
}
},
{
"pk": 4,
"model": "student.courseaccessrole",
"fields": {
"id": "4",
"org": "test_org",
"course_id": "course-v1:test_org+34039497242734583224814321005482849783+test_run",
"role": "finance_admin",
"user_id": "1"
}
}
]
......@@ -30,7 +30,7 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
# URL for instructor dash
cls.url = reverse('instructor_dashboard', kwargs={'course_id': cls.course.id.to_deprecated_string()})
cls.e_commerce_link = '<button type="button" class="btn-link" data-section="e-commerce">E-Commerce</button>'
cls.ecommerce_link = '<button type="button" class="btn-link" data-section="e-commerce">E-Commerce</button>'
def setUp(self):
super(TestECommerceDashboardViews, self).setUp()
......@@ -50,7 +50,7 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
Test Pass E-commerce Tab is in the Instructor Dashboard
"""
response = self.client.get(self.url)
self.assertIn(self.e_commerce_link, response.content)
self.assertIn(self.ecommerce_link, response.content)
# Coupons should show up for White Label sites with priced honor modes.
self.assertIn('Coupon Code List', response.content)
......@@ -61,7 +61,7 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
self.use_site(site=self.site_other)
self.client.login(username=self.instructor.username, password="test")
response = self.client.get(self.url)
self.assertIn(self.e_commerce_link, response.content)
self.assertIn(self.ecommerce_link, response.content)
self.assertIn('Create Enrollment Report', response.content)
def test_reports_section_not_under_e_commerce_tab(self):
......@@ -70,12 +70,12 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
value
"""
response = self.client.get(self.url)
self.assertIn(self.e_commerce_link, response.content)
self.assertIn(self.ecommerce_link, response.content)
self.assertNotIn('Create Enrollment Report', response.content)
def test_user_has_finance_admin_rights_in_e_commerce_tab(self):
response = self.client.get(self.url)
self.assertIn(self.e_commerce_link, response.content)
self.assertIn(self.ecommerce_link, response.content)
# Order/Invoice sales csv button text should render in e-commerce page
self.assertIn('Total Credit Card Purchases', response.content)
......@@ -96,7 +96,7 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
the instructor dashboard
"""
response = self.client.get(self.url)
self.assertIn(self.e_commerce_link, response.content)
self.assertIn(self.ecommerce_link, response.content)
# Total amount html should render in e-commerce page, total amount will be 0
course_honor_mode = CourseMode.mode_for_course(self.course.id, 'honor')
......@@ -351,6 +351,39 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
# Get the response value, ensure the Coupon section is not included.
response = self.client.get(self.url)
self.assertIn(self.e_commerce_link, response.content)
self.assertIn(self.ecommerce_link, response.content)
# Coupons should show up for White Label sites with priced honor modes.
self.assertNotIn('Coupons List', response.content)
def test_coupon_code_section_not_under_e_commerce_tab(self):
"""
Test Coupon Creation UI, under E-commerce Tab, should not be available in the Instructor Dashboard with
e-commerce course
"""
# Setup e-commerce course
CourseMode.objects.filter(course_id=self.course.id).update(sku='test_sku')
response = self.client.get(self.url)
self.assertIn(self.ecommerce_link, response.content)
self.assertNotIn('Coupon Code List', response.content)
def test_enrollment_codes_section_not_under_e_commerce_tab(self):
"""
Test Enrollment Codes UI, under E-commerce Tab, should not be available in the Instructor Dashboard with
e-commerce course
"""
# Setup e-commerce course
CourseMode.objects.filter(course_id=self.course.id).update(sku='test_sku')
response = self.client.get(self.url)
self.assertIn(self.ecommerce_link, response.content)
self.assertNotIn('<h3 class="hd hd-3">Enrollment Codes</h3>', response.content)
def test_enrollment_codes_section_visible_for_non_ecommerce_course(self):
"""
Test Enrollment Codes UI, under E-commerce Tab, should be available in the Instructor Dashboard with non
e-commerce course
"""
response = self.client.get(self.url)
self.assertIn(self.ecommerce_link, response.content)
self.assertIn('<h3 class="hd hd-3">Enrollment Codes</h3>', response.content)
......@@ -285,7 +285,8 @@ def _section_e_commerce(course, access, paid_mode, coupons_enabled, reports_enab
'coupons_enabled': coupons_enabled,
'reports_enabled': reports_enabled,
'course_price': course_price,
'total_amount': total_amount
'total_amount': total_amount,
'is_ecommerce_course': is_ecommerce_course(course_key)
}
return section_data
......@@ -695,3 +696,12 @@ def _section_metrics(course, access):
'post_metrics_data_csv_url': reverse('post_metrics_data_csv'),
}
return section_data
def is_ecommerce_course(course_key):
"""
Checks if the given course is an e-commerce course or not, by checking its SKU value from
CourseMode records for the course
"""
sku_count = len([mode.sku for mode in CourseMode.modes_for_course(course_key) if mode.sku])
return sku_count > 0
......@@ -14,7 +14,8 @@ import pytz
<div class="ecommerce-wrapper">
<div class="error-msgs" id="error-msg"></div>
<div id = "accordion">
<div class="wrap">
%if not section_data['is_ecommerce_course']:
<div class="wrap">
<h3 class="hd hd-3">${_('Enrollment Codes')}</h3>
<div>
%if section_data['sales_admin']:
......@@ -53,6 +54,7 @@ import pytz
<a id="registration_code_generation_link-trigger" href="#registration_code_generation_modal" rel="leanModal"></a>
</div>
</div>
%endif
<!-- end wrap -->
%if section_data['coupons_enabled']:
<div class="wrap">
......@@ -145,7 +147,7 @@ import pytz
</div>
</div><!-- end wrap -->
%endif
%if section_data['coupons_enabled']:
%if section_data['coupons_enabled'] and not section_data['is_ecommerce_course']:
<div class="wrap">
<h3 class="hd hd-3">${_("Coupon Code List")}</h3>
<div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment