def test_multiple_published_course_runs(self): """ Learner should not be eligible for one click purchase if: - program has a course with more than one published course run """ course_run_1 = CourseRunFactory(key=str(ModuleStoreCourseFactory().id), status='published') course_run_2 = CourseRunFactory(key=str(ModuleStoreCourseFactory().id), status='published') course = CourseFactory(course_runs=[course_run_1, course_run_2]) program = ProgramFactory( courses=[ CourseFactory(course_runs=[ CourseRunFactory(key=str(ModuleStoreCourseFactory().id), status='published') ]), course, CourseFactory(course_runs=[ CourseRunFactory(key=str(ModuleStoreCourseFactory().id), status='published') ]) ], is_program_eligible_for_one_click_purchase=True) data = ProgramMarketingDataExtender(program, self.user).extend() self.assertFalse(data['is_learner_eligible_for_one_click_purchase']) course_run_2['status'] = 'unpublished' data = ProgramMarketingDataExtender(program, self.user).extend() self.assertTrue(data['is_learner_eligible_for_one_click_purchase'])
def test_learner_eligibility_for_one_click_purchase(self): """ Learner should be eligible for one click purchase if: - program is eligible for one click purchase - learner is not enrolled in any of the course runs associated with the program """ data = ProgramMarketingDataExtender(self.program, self.user).extend() self.assertTrue(data['is_learner_eligible_for_one_click_purchase']) courses = [self._create_course(self.course_price)] program = ProgramFactory( courses=courses, is_program_eligible_for_one_click_purchase=False ) data = ProgramMarketingDataExtender(program, self.user).extend() self.assertFalse(data['is_learner_eligible_for_one_click_purchase']) courses.append(self._create_course(self.course_price, is_enrolled=True)) program2 = ProgramFactory( courses=courses, is_program_eligible_for_one_click_purchase=True ) data = ProgramMarketingDataExtender(program2, self.user).extend() self.assertFalse(data['is_learner_eligible_for_one_click_purchase'])
def test_learner_eligibility_for_one_click_purchase(self): """ Learner should be eligible for one click purchase if: - program is eligible for one click purchase - There are courses remaining that have not been purchased and enrolled in. """ data = ProgramMarketingDataExtender(self.program, self.user).extend() self.assertTrue(data['is_learner_eligible_for_one_click_purchase']) courses = [self._create_course(self.course_price)] program = ProgramFactory( courses=courses, is_program_eligible_for_one_click_purchase=False) data = ProgramMarketingDataExtender(program, self.user).extend() self.assertFalse(data['is_learner_eligible_for_one_click_purchase']) course1 = self._create_course(self.course_price) course2 = self._create_course(self.course_price) CourseEnrollmentFactory(user=self.user, course_id=course1['course_runs'][0]['key'], mode='verified') CourseEnrollmentFactory(user=self.user, course_id=course2['course_runs'][0]['key'], mode='audit') program2 = ProgramFactory( courses=[course1, course2], is_program_eligible_for_one_click_purchase=True, applicable_seat_types=['verified'], ) data = ProgramMarketingDataExtender(program2, self.user).extend() self.assertTrue(data['is_learner_eligible_for_one_click_purchase'])
def test_course_pricing(self): data = ProgramMarketingDataExtender(self.program, self.user).extend() program_full_price = self.course_price * self.number_of_courses self.assertEqual(data['number_of_courses'], self.number_of_courses) self.assertEqual(data['full_program_price'], program_full_price) self.assertEqual(data['avg_price_per_course'], program_full_price / self.number_of_courses)
def test_fetching_program_discounted_price_as_anonymous_user(self): """ Anonymous users should see the purchase button same way the authenticated users do when the program is eligible for one click purchase. """ self._prepare_program_for_discounted_price_calculation_endpoint() mock_discount_data = { 'total_incl_tax_excl_discounts': 200.0, 'currency': 'USD', 'total_incl_tax': 50.0 } httpretty.register_uri( httpretty.GET, self.ECOMMERCE_CALCULATE_DISCOUNT_ENDPOINT, body=json.dumps(mock_discount_data), content_type='application/json' ) data = ProgramMarketingDataExtender(self.program, AnonymousUserFactory()).extend() self._update_discount_data(mock_discount_data) self.assertEqual( data['skus'], [course['course_runs'][0]['seats'][0]['sku'] for course in self.program['courses']] ) self.assertEqual(data['discount_data'], mock_discount_data)
def test_fetching_program_discounted_price(self): """ Authenticated users eligible for one click purchase should see the purchase button - displaying program's discounted price if it exists. - leading to ecommerce basket page """ self._prepare_program_for_discounted_price_calculation_endpoint() mock_discount_data = { 'total_incl_tax_excl_discounts': 200.0, 'currency': 'USD', 'total_incl_tax': 50.0 } httpretty.register_uri( httpretty.GET, self.ECOMMERCE_CALCULATE_DISCOUNT_ENDPOINT, body=json.dumps(mock_discount_data), content_type='application/json' ) data = ProgramMarketingDataExtender(self.program, self.user).extend() self._update_discount_data(mock_discount_data) self.assertEqual( data['skus'], [course['course_runs'][0]['seats'][0]['sku'] for course in self.program['courses']] ) self.assertEqual(data['discount_data'], mock_discount_data)
def test_fetching_program_discounted_price_no_applicable_seats(self): """ User shouldn't be able to do a one click purchase of a program if a program has no applicable seat types. """ data = ProgramMarketingDataExtender(self.program, self.user).extend() self.assertEqual(len(data['skus']), 0)
def test_can_enroll(self, can_enroll, mock_has_access): """ Verify that the student's can_enroll status is included. """ mock_has_access.return_value = can_enroll data = ProgramMarketingDataExtender(self.program, self.user).extend() self.assertEqual(data['courses'][0]['course_runs'][0]['can_enroll'], can_enroll)
def test_course_pricing_when_all_course_runs_have_no_seats(self): # Create three seatless course runs and add them to the program course_runs = [] for __ in range(3): course = ModuleStoreCourseFactory() course = self.update_course(course, self.user.id) course_runs.append(CourseRunFactory(key=unicode(course.id), seats=[])) program = ProgramFactory(courses=[CourseFactory(course_runs=course_runs)]) data = ProgramMarketingDataExtender(program, self.user).extend() self.assertEqual(data['number_of_courses'], len(program['courses'])) self.assertEqual(data['full_program_price'], 0.0) self.assertEqual(data['avg_price_per_course'], 0.0)
def test_fetching_program_discounted_price_api_exception_caught(self): """ User should be able to do a one click purchase of a program even if the ecommerce API throws an exception during the calculation of program discounted price. """ self._prepare_program_for_discounted_price_calculation_endpoint() httpretty.register_uri(httpretty.GET, self.ECOMMERCE_CALCULATE_DISCOUNT_ENDPOINT, status=400, content_type='application/json') data = ProgramMarketingDataExtender(self.program, self.user).extend() self.assertEqual(data['skus'], [ course['course_runs'][0]['seats'][0]['sku'] for course in self.program['courses'] ])
def test_instructors(self): data = ProgramMarketingDataExtender(self.program, self.user).extend() self.program.update(self.instructors['instructors']) self.assertEqual(data, self.program)