예제 #1
0
    def test_get_offers_for_single_course_voucher(self):
        """ Verify that the course offers data is returned for a single course voucher. """
        self.mock_access_token_response()
        course, seat = self.create_course_and_seat()
        new_range = RangeFactory(products=[seat, ])
        voucher, __ = prepare_voucher(_range=new_range, benefit_value=10)
        benefit = voucher.offers.first().benefit
        request = self.prepare_offers_listing_request(voucher.code)
        self.mock_course_run_detail_endpoint(
            course, discovery_api_url=self.site_configuration.discovery_api_url
        )
        offers = VoucherViewSet().get_offers(request=request, voucher=voucher)['results']
        first_offer = offers[0]

        self.assertEqual(len(offers), 1)
        self.assertDictEqual(first_offer, {
            'benefit': {
                'type': benefit.type,
                'value': benefit.value
            },
            'contains_verified': True,
            'course_start_date': '2013-02-05T05:00:00Z',
            'id': course.id,
            'image_url': '/path/to/image.jpg',
            'multiple_credit_providers': False,
            'organization': CourseKey.from_string(course.id).org,
            'credit_provider_price': None,
            'seat_type': course.type,
            'stockrecords': serializers.StockRecordSerializer(seat.stockrecords.first()).data,
            'title': course.name,
            'voucher_end_date': voucher.end_datetime,
        })
예제 #2
0
    def test_omitting_already_bought_credit_seat(self):
        """ Verify a seat that the user bought is omitted from offer page results. """
        self.mock_access_token_response()
        products, request, voucher = self.prepare_get_offers_response(
            quantity=2, seat_type='credit')
        self.mock_eligibility_api(request, self.user, 'a/b/c', eligible=True)
        offers = VoucherViewSet().get_offers(request=request,
                                             voucher=voucher)['results']
        self.assertEqual(len(offers), 2)

        order = OrderFactory(user=self.user)
        order.lines.add(
            OrderLineFactory(product=products[0], partner_sku='test_sku'))
        offers = VoucherViewSet().get_offers(request=request,
                                             voucher=voucher)['results']
        self.assertEqual(len(offers), 1)
예제 #3
0
    def test_get_offers_for_course_catalog_voucher(self):
        """ Verify that the course offers data is returned for a course catalog voucher. """
        catalog_id = 1
        catalog_query = '*:*'

        # Populate database for the test case.
        course, seat = self.create_course_and_seat()
        new_range, __ = Range.objects.get_or_create(
            course_catalog=catalog_id, course_seat_types='verified')
        new_range.add_product(seat)
        voucher, __ = prepare_voucher(_range=new_range, benefit_value=10)

        # Mock network calls
        self.mock_dynamic_catalog_course_runs_api(
            query=catalog_query,
            course_run=course,
            discovery_api_url=self.site_configuration.discovery_api_url)
        self.mock_fetch_course_catalog(
            catalog_id=catalog_id,
            expected_query=catalog_query,
            discovery_api_url=self.site_configuration.discovery_api_url)

        benefit = voucher.offers.first().benefit
        request = self.prepare_offers_listing_request(voucher.code)
        offers = VoucherViewSet().get_offers(request=request,
                                             voucher=voucher)['results']
        first_offer = offers[0]

        # Verify that offers are returned when voucher is created using course catalog
        self.assertEqual(len(offers), 1)
        self.assertDictEqual(
            first_offer, {
                'benefit': {
                    'type': benefit.type,
                    'value': benefit.value
                },
                'contains_verified':
                True,
                'course_start_date':
                '2016-05-01T00:00:00Z',
                'id':
                course.id,
                'image_url':
                'path/to/the/course/image',
                'multiple_credit_providers':
                False,
                'organization':
                CourseKey.from_string(course.id).org,
                'credit_provider_price':
                None,
                'seat_type':
                course.type,
                'stockrecords':
                serializers.StockRecordSerializer(
                    seat.stockrecords.first()).data,
                'title':
                course.name,
                'voucher_end_date':
                voucher.end_datetime,
            })
예제 #4
0
 def test_get_offers_for_multiple_courses_voucher(self):
     """ Verify that the course offers data is returned for a multiple courses voucher. """
     self.mock_access_token_response()
     course, seat = self.create_course_and_seat()
     self.mock_course_runs_endpoint(
         self.site_configuration.discovery_api_url, query='*:*', course_run=course
     )
     new_range, __ = Range.objects.get_or_create(catalog_query='*:*', course_seat_types='verified')
     new_range.add_product(seat)
     voucher, __ = prepare_voucher(_range=new_range, benefit_value=10)
     benefit = voucher.offers.first().benefit
     request = self.prepare_offers_listing_request(voucher.code)
     offers = VoucherViewSet().get_offers(request=request, voucher=voucher)['results']
     first_offer = offers[0]
     self.assertEqual(len(offers), 1)
     self.assertDictEqual(first_offer, {
         'benefit': {
             'type': benefit.type,
             'value': benefit.value
         },
         'contains_verified': True,
         'course_start_date': '2016-05-01T00:00:00Z',
         'id': course.id,
         'image_url': 'path/to/the/course/image',
         'multiple_credit_providers': False,
         'organization': CourseKey.from_string(course.id).org,
         'credit_provider_price': None,
         'seat_type': course.type,
         'stockrecords': serializers.StockRecordSerializer(seat.stockrecords.first()).data,
         'title': course.name,
         'voucher_end_date': voucher.end_datetime,
     })
예제 #5
0
    def test_omitting_expired_courses(self):
        """Verify professional courses who's enrollment end datetime have passed are omitted."""
        no_date_seat = CourseFactory().create_or_update_seat(
            'professional', False, 100, partner=self.partner)
        valid_seat = CourseFactory().create_or_update_seat(
            'professional', False, 100, partner=self.partner)
        expired_seat = CourseFactory().create_or_update_seat(
            'professional', False, 100, partner=self.partner)

        course_discovery_results = [{
            'key': no_date_seat.attr.course_key,
            'enrollment_end': None,
        }, {
            'key':
            valid_seat.attr.course_key,
            'enrollment_end':
            str(now() + datetime.timedelta(days=1)),
        }, {
            'key':
            expired_seat.attr.course_key,
            'enrollment_end':
            str(now() - datetime.timedelta(days=1)),
        }]

        products, __ = VoucherViewSet().retrieve_course_objects(
            course_discovery_results, 'professional')
        self.assertIn(no_date_seat, products)
        self.assertIn(valid_seat, products)
        self.assertNotIn(expired_seat, products)
예제 #6
0
    def test_multiple_providers(self):
        """ Verify offer contains information about credit providers. """
        course = CourseFactory()
        seat1 = course.create_or_update_seat('credit',
                                             False,
                                             100,
                                             partner=self.partner,
                                             credit_provider='test_provider_1')
        seat2 = course.create_or_update_seat('credit',
                                             False,
                                             100,
                                             partner=self.partner,
                                             credit_provider='test_provider_2')
        self.assertEqual(
            Product.objects.filter(parent=seat1.parent).count(), 2)

        self.mock_access_token_response()
        __, request, voucher = self.prepare_get_offers_response(
            seats=[seat1, seat2], seat_type='credit')
        self.mock_eligibility_api(request, self.user, course.id)
        offers = VoucherViewSet().get_offers(request=request,
                                             voucher=voucher)['results']
        for offer in offers:
            self.assertTrue(offer['multiple_credit_providers'])
            self.assertIsNone(offer['credit_provider_price'])
예제 #7
0
 def test_omitting_uneligible_credit_seat(self, offer_num, eligible):
     """ Verify a seat that the user is not eligible for is omitted from offer page results. """
     self.mock_access_token_response()
     products, request, voucher = self.prepare_get_offers_response(quantity=1, seat_type='credit')
     self.mock_eligibility_api(request, self.user, products[0].attr.course_key, eligible=eligible)
     offers = VoucherViewSet().get_offers(request=request, voucher=voucher)['results']
     self.assertEqual(len(offers), offer_num)
예제 #8
0
    def test_omitting_unavailable_seats(self):
        """ Verify an unavailable seat is omitted from offer page results. """
        course1, seat1 = self.create_course_and_seat()
        course2, seat2 = self.create_course_and_seat()
        course_run_info = {
            'count':
            2,
            'next':
            'path/to/the/next/page',
            'results': [{
                'key': course1.id,
                'title': course1.name,
                'start': '2016-05-01T00:00:00Z',
                'image': {
                    'src': 'path/to/the/course/image'
                }
            }, {
                'key': course2.id,
                'title': course2.name,
                'start': '2016-05-01T00:00:00Z',
                'image': {
                    'src': 'path/to/the/course/image'
                }
            }]
        }

        self.mock_dynamic_catalog_course_runs_api(
            query='*:*', course_run_info=course_run_info)
        new_range, __ = Range.objects.get_or_create(catalog_query='*:*')
        new_range.add_product(seat1)
        new_range.add_product(seat2)
        voucher, __ = prepare_voucher(_range=new_range)
        voucher, products = get_voucher_and_products_from_code(voucher.code)
        factory = APIRequestFactory()
        request = factory.get('/?code={}&page_size=6'.format(voucher.code))
        request.site = self.site
        request.strategy = DefaultStrategy()
        offers = VoucherViewSet().get_offers(products=products,
                                             request=request,
                                             voucher=voucher)['results']
        self.assertEqual(len(offers), 2)

        products[1].expires = pytz.utc.localize(datetime.datetime.min)
        offers = VoucherViewSet().get_offers(products=products,
                                             request=request,
                                             voucher=voucher)['results']
        self.assertEqual(len(offers), 1)
예제 #9
0
 def test_get_offers_for_enterprise_catalog_voucher(self):
     """ Verify that the course offers data is returned for an enterprise catalog voucher. """
     Switch.objects.update_or_create(
         name=ENTERPRISE_OFFERS_FOR_COUPONS_SWITCH,
         defaults={'active': False})
     self.mock_access_token_response()
     course, seat = self.create_course_and_seat()
     enterprise_catalog_id = str(uuid4())
     self.mock_enterprise_catalog_course_endpoint(
         self.site_configuration.enterprise_api_url,
         enterprise_catalog_id,
         course_run=course)
     new_range, __ = Range.objects.get_or_create(
         catalog_query='*:*',
         course_seat_types='verified',
         enterprise_customer=str(uuid4()),
         enterprise_customer_catalog=enterprise_catalog_id,
     )
     new_range.add_product(seat)
     voucher, __ = prepare_voucher(_range=new_range, benefit_value=10)
     benefit = voucher.offers.first().benefit
     request = self.prepare_offers_listing_request(voucher.code)
     offers = VoucherViewSet().get_offers(request=request,
                                          voucher=voucher)['results']
     first_offer = offers[0]
     self.assertEqual(len(offers), 1)
     self.assertDictEqual(
         first_offer, {
             'benefit': {
                 'type': get_benefit_type(benefit),
                 'value': benefit.value
             },
             'contains_verified':
             True,
             'course_start_date':
             '2016-05-01T00:00:00Z',
             'id':
             course.id,
             'image_url':
             'path/to/the/course/image',
             'multiple_credit_providers':
             False,
             'organization':
             CourseKey.from_string(course.id).org,
             'credit_provider_price':
             None,
             'seat_type':
             course.type,
             'stockrecords':
             serializers.StockRecordSerializer(
                 seat.stockrecords.first()).data,
             'title':
             course.name,
             'voucher_end_date':
             voucher.end_datetime,
         })
예제 #10
0
 def test_get_offers_for_enterprise_offer_no_catalog(self):
     """ Verify that the course offers data is returned for an enterprise catalog voucher. """
     self.mock_access_token_response()
     enterprise_customer_id = str(uuid4())
     voucher = prepare_enterprise_voucher(
         benefit_value=10,
         enterprise_customer=enterprise_customer_id,
     )
     request = self.prepare_offers_listing_request(voucher.code)
     offers = VoucherViewSet().get_offers(request=request, voucher=voucher)['results']
     self.assertEqual(len(offers), 0)
예제 #11
0
 def test_get_offers_for_enterprise_offer(self):
     """ Verify that the course offers data is returned for an enterprise catalog voucher. """
     self.mock_access_token_response()
     course, seat = self.create_course_and_seat()
     enterprise_customer_id = str(uuid4())
     enterprise_catalog_id = str(uuid4())
     self.mock_enterprise_catalog_course_endpoint(
         self.site_configuration.enterprise_api_url,
         enterprise_catalog_id,
         course_run=course)
     voucher = prepare_enterprise_voucher(
         benefit_value=10,
         enterprise_customer=enterprise_customer_id,
         enterprise_customer_catalog=enterprise_catalog_id)
     benefit = voucher.offers.first().benefit
     request = self.prepare_offers_listing_request(voucher.code)
     offers = VoucherViewSet().get_offers(request=request,
                                          voucher=voucher)['results']
     first_offer = offers[0]
     self.assertEqual(len(offers), 1)
     self.assertDictEqual(
         first_offer, {
             'benefit': {
                 'type': get_benefit_type(benefit),
                 'value': benefit.value
             },
             'contains_verified':
             True,
             'course_start_date':
             '2016-05-01T00:00:00Z',
             'id':
             course.id,
             'image_url':
             'path/to/the/course/image',
             'multiple_credit_providers':
             False,
             'organization':
             CourseKey.from_string(course.id).org,
             'credit_provider_price':
             None,
             'seat_type':
             seat.attr.certificate_type,
             'stockrecords':
             serializers.StockRecordSerializer(
                 seat.stockrecords.first()).data,
             'title':
             course.name,
             'voucher_end_date':
             voucher.end_datetime,
         })
예제 #12
0
    def test_omitting_unavailable_seats(self):
        """ Verify an unavailable seat is omitted from offer page results. """
        products, request, voucher = self.prepare_get_offers_response(quantity=2)
        url = self.build_offers_url(voucher)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data['results']), 2)

        product = products[0]
        product.expires = pytz.utc.localize(datetime.datetime.min)
        product.save()

        offers = VoucherViewSet().get_offers(request=request, voucher=voucher)['results']
        self.assertEqual(len(offers), 1)
예제 #13
0
 def test_get_offers_for_enterprise_offer_switch_on_no_catalog(self):
     """ Verify that the course offers data is returned for an enterprise catalog voucher. """
     Switch.objects.update_or_create(
         name=ENTERPRISE_OFFERS_FOR_COUPONS_SWITCH,
         defaults={'active': True})
     self.mock_access_token_response()
     enterprise_customer_id = str(uuid4())
     voucher = prepare_enterprise_voucher(
         benefit_value=10,
         enterprise_customer=enterprise_customer_id,
     )
     request = self.prepare_offers_listing_request(voucher.code)
     offers = VoucherViewSet().get_offers(request=request,
                                          voucher=voucher)['results']
     self.assertEqual(len(offers), 0)
예제 #14
0
    def test_voucher_offers_listing_catalog_query_exception(self, return_value, method):
        """
        Verify the endpoint returns status 200 and an empty list of course offers
        when all product Courses and Stock Records are not found
        and range has a catalog query
        """
        course, seat = self.create_course_and_seat()
        self.mock_dynamic_catalog_course_runs_api(query='*:*', course_run=course)
        new_range, __ = Range.objects.get_or_create(catalog_query='*:*', course_seat_types='verified')
        new_range.add_product(seat)
        voucher, __ = prepare_voucher(_range=new_range)
        request = self.prepare_offers_listing_request(voucher.code)

        with mock.patch(method, mock.Mock(return_value=return_value)):
            offers = VoucherViewSet().get_offers(request=request, voucher=voucher)['results']
            self.assertEqual(len(offers), 0)
예제 #15
0
    def test_get_offers_for_single_course_voucher(self):
        """ Verify that the course offers data is returned for a single course voucher. """
        course, seat = self.create_course_and_seat()
        new_range = RangeFactory(products=[
            seat,
        ])
        voucher, __ = prepare_voucher(_range=new_range, benefit_value=10)
        voucher, products = get_voucher_and_products_from_code(voucher.code)
        benefit = voucher.offers.first().benefit
        request = self.prepare_offers_listing_request(voucher.code)
        self.mock_course_api_response(course=course)
        offers = VoucherViewSet().get_offers(products=products,
                                             request=request,
                                             voucher=voucher)
        first_offer = offers[0]

        self.assertEqual(len(offers), 1)
        self.assertDictEqual(
            first_offer, {
                'benefit': {
                    'type': benefit.type,
                    'value': benefit.value
                },
                'contains_verified':
                True,
                'course_start_date':
                '2013-02-05T05:00:00Z',
                'id':
                course.id,
                'image_url':
                get_lms_url(
                    '/asset-v1:test+test+test+type@asset+block@images_course_image.jpg'
                ),
                'organization':
                CourseKey.from_string(course.id).org,
                'seat_type':
                course.type,
                'stockrecords':
                serializers.StockRecordSerializer(
                    seat.stockrecords.first()).data,
                'title':
                course.name,
                'voucher_end_date':
                voucher.end_datetime
            })
예제 #16
0
    def test_get_offers(self):
        """ Verify that the course offers data is returned. """
        course, seat = self.create_course_and_seat()
        new_range = RangeFactory(products=[
            seat,
        ])
        voucher, __ = prepare_voucher(_range=new_range, benefit_value=10)
        voucher, products = get_voucher_and_products_from_code(voucher.code)
        benefit = voucher.offers.first().benefit
        request = self.prepare_offers_listing_request(voucher.code)
        self.mock_dynamic_catalog_course_runs_api(
            course_run=course, query=new_range.catalog_query)
        offers = VoucherViewSet().get_offers(products=products,
                                             request=request,
                                             voucher=voucher)
        first_offer = offers[0]

        self.assertEqual(len(offers), 1)
        self.assertDictEqual(
            first_offer, {
                'benefit': {
                    'type': benefit.type,
                    'value': benefit.value
                },
                'contains_verified':
                True,
                'course_start_date':
                '2016-05-01T00:00:00Z',
                'id':
                course.id,
                'image_url':
                'path/to/the/course/image',
                'organization':
                CourseKey.from_string(course.id).org,
                'seat_type':
                course.type,
                'stockrecords':
                serializers.StockRecordSerializer(
                    seat.stockrecords.first()).data,
                'title':
                course.name,
                'voucher_end_date':
                voucher.end_datetime
            })
예제 #17
0
    def test_get_course_offer_data(self):
        """ Verify that the course offers data is properly formatted. """
        benefit = BenefitFactory()
        course, seat = self.create_course_and_seat()
        course_info = {
            'start': '2016-05-01T00:00:00Z',
            'image': {
                'src': 'path/to/the/course/image'
            }
        }
        stock_record = seat.stockrecords.first()
        voucher = VoucherFactory()

        offer = VoucherViewSet().get_course_offer_data(
            benefit=benefit,
            course=course,
            course_info=course_info,
            credit_provider_price=None,
            multiple_credit_providers=False,
            is_verified=True,
            product=seat,
            stock_record=stock_record,
            voucher=voucher)

        self.assertDictEqual(
            offer, {
                'benefit': {
                    'type': get_benefit_type(benefit),
                    'value': benefit.value
                },
                'contains_verified': True,
                'course_start_date': course_info['start'],
                'id': course.id,
                'image_url': course_info['image']['src'],
                'multiple_credit_providers': False,
                'organization': CourseKey.from_string(course.id).org,
                'credit_provider_price': None,
                'seat_type': seat.attr.certificate_type,
                'stockrecords':
                serializers.StockRecordSerializer(stock_record).data,
                'title': course.name,
                'voucher_end_date': voucher.end_datetime,
            })
예제 #18
0
    def test_get_course_offer_verify_null_fields(self):
        """ Verify that the course offers data is properly formatted. """
        benefit = BenefitFactory()
        course, seat = self.create_course_and_seat()
        course_info = {
            'start': None,
            'image': None,
        }
        stock_record = seat.stockrecords.first()
        voucher = VoucherFactory()
        offer = VoucherViewSet().get_course_offer_data(
            benefit=benefit,
            course=course,
            course_info=course_info,
            is_verified=True,
            stock_record=stock_record,
            voucher=voucher)

        self.assertEqual(offer['image_url'], '')
        self.assertEqual(offer['course_start_date'], None)
예제 #19
0
    def test_voucher_offers_listing_product_not_found(self, code):
        """ Verify the endpoint returns status 400 Bad Request. """
        request = self.prepare_offers_listing_request(code)
        response = VoucherViewSet().offers(request)

        self.assertEqual(response.status_code, 400)
예제 #20
0
 def setUp(self):
     super(VoucherViewOffersEndpointTests, self).setUp()
     self.endpointView = VoucherViewSet.as_view({'get': 'offers'})
     self.factory = APIRequestFactory()
     request = self.factory.get('/page=1')
     self.endpointView.request = request
예제 #21
0
 def setUp(self):
     super(VoucherViewOffersEndpointTests, self).setUp()
     self.endpointView = VoucherViewSet.as_view({'get': 'offers'})
     self.factory = APIRequestFactory()
     request = self.factory.get('/page=1')
     self.endpointView.request = request