def test_successful_zero_dollar_refund_no_tracking(self, mock_track):
     """
     Verify that tracking events are not emitted for refunds corresponding
     to a total credit of 0.
     """
     order = self.create_order(free=True)
     create_refunds([order], self.course.id)
     self.assertFalse(mock_track.called)
示例#2
0
    def test_successful_zero_dollar_refund_no_tracking(self, mock_track):
        """
        Verify that tracking events are not emitted for refunds corresponding
        to a total credit of 0.
        """
        order = self.create_order(free=True)
        create_refunds([order], self.course.id)

        # Verify that no business intelligence event was emitted. Refunds corresponding
        # to a total credit of 0 are automatically approved upon creation.
        self.assertFalse(mock_track.called)
示例#3
0
    def test_successful_zero_dollar_refund_no_tracking(self, mock_track):
        """
        Verify that tracking events are not emitted for refunds corresponding
        to a total credit of 0.
        """
        order = self.create_order(free=True)
        create_refunds([order], self.course.id)

        # Verify that no business intelligence event was emitted. Refunds corresponding
        # to a total credit of 0 are automatically approved upon creation.
        self.assertFalse(mock_track.called)
示例#4
0
    def test_successful_zero_dollar_refund_no_tracking(self, mock_track):
        """
        Verify that tracking events are not emitted for refunds corresponding
        to a total credit of 0.
        """
        order = self.create_order(free=True)
        create_refunds([order], self.course.id)

        # Ensure that only 'Product Added' event is emitted (in order creation) and not 'Order Completion' event.
        self.assertEqual(mock_track.call_count, 1)
        event_name = mock_track.call_args[0][1]
        self.assertEqual(event_name, 'Product Added')
示例#5
0
    def test_create_refunds_with_existing_refund(self):
        """ The method should NOT create refunds for lines that have already been refunded. """
        order = self.create_order()
        RefundLineFactory(order_line=order.lines.first())

        actual = create_refunds([order], self.course.id)
        self.assertEqual(actual, [])
示例#6
0
 def test_create_refunds(self):
     """ The method should create refunds for orders/lines that have not been refunded. """
     order = self.create_order()
     actual = create_refunds([order], self.course.id)
     refund = Refund.objects.get(order=order)
     self.assertEqual(actual, [refund])
     self.assert_refund_matches_order(refund, order)
示例#7
0
    def create(self, request, *args, **kwargs):
        """ Creates refunds, if eligible orders exist. """
        course_id = request.data.get('course_id')
        username = request.data.get('username')

        if not course_id:
            raise BadRequestException('No course_id specified.')

        # We should always have a username value as long as CanActForUser is in place.
        if not username:  # pragma: no cover
            raise BadRequestException('No username specified.')

        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            raise BadRequestException('User "{}" does not exist.'.format(username))

        refunds = []

        # We can only create refunds if the user has orders.
        if user.orders.exists():
            orders = find_orders_associated_with_course(user, course_id)
            refunds = create_refunds(orders, course_id)

        # Return HTTP 201 if we created refunds.
        if refunds:
            refund_ids = [refund.id for refund in refunds]
            return Response(refund_ids, status=status.HTTP_201_CREATED)

        # Return HTTP 200 if we did NOT create refunds.
        return Response([], status=status.HTTP_200_OK)
示例#8
0
    def create(self, request, *args, **kwargs):
        """ Creates refunds, if eligible orders exist. """
        course_id = request.data.get('course_id')
        username = request.data.get('username')

        if not course_id:
            raise BadRequestException('No course_id specified.')

        # We should always have a username value as long as CanActForUser is in place.
        if not username:  # pragma: no cover
            raise BadRequestException('No username specified.')

        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            raise BadRequestException(
                'User "{}" does not exist.'.format(username))

        refunds = []

        # We can only create refunds if the user has orders.
        if user.orders.exists():
            orders = find_orders_associated_with_course(user, course_id)
            refunds = create_refunds(orders, course_id)

        # Return HTTP 201 if we created refunds.
        if refunds:
            refund_ids = [refund.id for refund in refunds]
            return Response(refund_ids, status=status.HTTP_201_CREATED)

        # Return HTTP 200 if we did NOT create refunds.
        return Response([], status=status.HTTP_200_OK)
示例#9
0
    def test_create_refunds_with_existing_refund(self):
        """ The method should NOT create refunds for lines that have already been refunded. """
        order = self.create_order()
        RefundLineFactory(order_line=order.lines.first())

        actual = create_refunds([order], self.course_id)
        self.assertEqual(actual, [])
示例#10
0
 def test_create_refunds(self):
     """ The method should create refunds for orders/lines that have not been refunded. """
     order = self.create_order()
     actual = create_refunds([order], self.course_id)
     refund = Refund.objects.get(order=order)
     self.assertEqual(actual, [refund])
     self.assert_refund_matches_order(refund, order)
示例#11
0
    def create(self, request, *args, **kwargs):
        """
        Creates refunds, if eligible orders exist.

        This supports creating refunds for both course runs as well as course entitlements.

        Arguments:
            username (string): This is required by both types of refund

            course_run refund:
            course_id (string): The course_id for wchich to refund for the given user

            course_entitlement refund:
            order_number (string): The order for which to refund the coures entitlement
            entitlement_uuid (string): The UUID for the course entitlement for the given order to refund

        Returns:
            refunds (list): List of refunds created
        """

        course_id = request.data.get('course_id')
        username = request.data.get('username')
        order_number = request.data.get('order_number')
        entitlement_uuid = request.data.get('entitlement_uuid')

        refunds = []

        # We should always have a username value as long as CanActForUser is in place.
        if not username:  # pragma: no cover
            raise BadRequestException('No username specified.')

        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            raise BadRequestException('User "{}" does not exist.'.format(username))

        # Try and create a refund for the passed in order
        if entitlement_uuid:
            try:
                order = user.orders.get(number=order_number)
                refunds = create_refunds_for_entitlement(order, entitlement_uuid)
            except (Order.DoesNotExist, OrderLine.DoesNotExist):
                raise BadRequestException('Order {} does not exist.'.format(order_number))
        else:
            if not course_id:
                raise BadRequestException('No course_id specified.')

            # We can only create refunds if the user has orders.
            if user.orders.exists():
                orders = find_orders_associated_with_course(user, course_id)
                refunds = create_refunds(orders, course_id)

        # Return HTTP 201 if we created refunds.
        if refunds:
            refund_ids = [refund.id for refund in refunds]
            return Response(refund_ids, status=status.HTTP_201_CREATED)

        # Return HTTP 200 if we did NOT create refunds.
        return Response([], status=status.HTTP_200_OK)
示例#12
0
    def setUp(self):
        super(RefundTrackingTests, self).setUp()

        self.user = UserFactory()
        self.order = self.create_order()
        self.refund = create_refunds([self.order], self.course.id)[0]
示例#13
0
    def create(self, request, *args, **kwargs):
        """
        Creates refunds, if eligible orders exist.

        This supports creating refunds for both course runs as well as course entitlements.

        Arguments:
            username (string): This is required by both types of refund

            course_run refund:
            course_id (string): The course_id for which to refund for the given user

            course_entitlement refund:
            order_number (string): The order for which to refund the course entitlement
            entitlement_uuid (string): The UUID for the course entitlement for the given order to refund

        Returns:
            refunds (list): List of refunds created

         Side effects:
            If the given user does not have an LMS user id, tries to find it. If found, adds the id to the user and
            saves the user. If the id cannot be found, writes custom metrics to record this fact.
        """

        course_id = request.data.get('course_id')
        username = request.data.get('username')
        order_number = request.data.get('order_number')
        entitlement_uuid = request.data.get('entitlement_uuid')

        refunds = []

        # We should always have a username value as long as CanActForUser is in place.
        if not username:  # pragma: no cover
            raise BadRequestException('No username specified.')

        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            raise BadRequestException(
                'User "{}" does not exist.'.format(username))

        # Ensure the user has an LMS user id
        try:
            if request.user.is_authenticated():
                requested_by = request.user.id
            else:  # pragma: no cover
                requested_by = None
            called_from = u'refund processing for user {user_id} requested by {requested_by}'.format(
                user_id=user.id, requested_by=requested_by)
            user.add_lms_user_id('ecommerce_missing_lms_user_id_refund',
                                 called_from)
        except MissingLmsUserIdException:
            raise BadRequestException(
                'User {} does not have an LMS user id.'.format(user.id))

        # Try and create a refund for the passed in order
        if entitlement_uuid:
            try:
                order = user.orders.get(number=order_number)
                refunds = create_refunds_for_entitlement(
                    order, entitlement_uuid)
            except (Order.DoesNotExist, OrderLine.DoesNotExist):
                raise BadRequestException(
                    'Order {} does not exist.'.format(order_number))
        else:
            if not course_id:
                raise BadRequestException('No course_id specified.')

            # We can only create refunds if the user has orders.
            if user.orders.exists():
                orders = find_orders_associated_with_course(user, course_id)
                refunds = create_refunds(orders, course_id)

        # Return HTTP 201 if we created refunds.
        if refunds:
            refund_ids = [refund.id for refund in refunds]
            return Response(refund_ids, status=status.HTTP_201_CREATED)

        # Return HTTP 200 if we did NOT create refunds.
        return Response([], status=status.HTTP_200_OK)
示例#14
0
 def setUp(self):
     super(RefundTrackingTests, self).setUp()
     self.user = UserFactory(lms_user_id=6179)
     self.refund = create_refunds([self.create_order()], self.course.id)[0]
示例#15
0
    def create(self, request, *args, **kwargs):
        """
        Creates refunds, if eligible orders exist.

        This supports creating refunds for both course runs as well as course entitlements.

        Arguments:
            username (string): This is required by both types of refund

            course_run refund:
            course_id (string): The course_id for which to refund for the given user

            course_entitlement refund:
            order_number (string): The order for which to refund the course entitlement
            entitlement_uuid (string): The UUID for the course entitlement for the given order to refund

        Returns:
            refunds (list): List of refunds created

        Side effect:
            If the LMS user_id cannot be found, writes custom metric: 'ecommerce_missing_lms_user_id_refund'
        """

        course_id = request.data.get('course_id')
        username = request.data.get('username')
        order_number = request.data.get('order_number')
        entitlement_uuid = request.data.get('entitlement_uuid')

        refunds = []

        # We should always have a username value as long as CanActForUser is in place.
        if not username:  # pragma: no cover
            raise BadRequestException('No username specified.')

        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            raise BadRequestException(
                'User "{}" does not exist.'.format(username))

        if not user.lms_user_id_with_metric(usage='refund'):
            requested_by = None
            if request.user.is_authenticated():
                requested_by = request.user.id
            # TODO: Change this to an error once we can successfully get the id from social auth and the db.
            # See REVMI-249 and REVMI-269
            monitoring_utils.set_custom_metric(
                'ecommerce_missing_lms_user_id_refund', user.id)
            logger.warn(
                u'Could not find lms_user_id for user %s when processing refund requested by %s',
                user.id, requested_by)

        # Try and create a refund for the passed in order
        if entitlement_uuid:
            try:
                order = user.orders.get(number=order_number)
                refunds = create_refunds_for_entitlement(
                    order, entitlement_uuid)
            except (Order.DoesNotExist, OrderLine.DoesNotExist):
                raise BadRequestException(
                    'Order {} does not exist.'.format(order_number))
        else:
            if not course_id:
                raise BadRequestException('No course_id specified.')

            # We can only create refunds if the user has orders.
            if user.orders.exists():
                orders = find_orders_associated_with_course(user, course_id)
                refunds = create_refunds(orders, course_id)

        # Return HTTP 201 if we created refunds.
        if refunds:
            refund_ids = [refund.id for refund in refunds]
            return Response(refund_ids, status=status.HTTP_201_CREATED)

        # Return HTTP 200 if we did NOT create refunds.
        return Response([], status=status.HTTP_200_OK)