Commit 3cea5c8b by christopher lee Committed by Christopher Lee

Remove analytics calls for temporary basket calculation

LEARNER-4968
parent f887a4b4
...@@ -566,6 +566,20 @@ class BasketCalculateViewTests(ProgramTestMixin, TestCase): ...@@ -566,6 +566,20 @@ class BasketCalculateViewTests(ProgramTestMixin, TestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, expected) self.assertEqual(response.data, expected)
@httpretty.activate
def test_basket_calculate_does_not_call_tracking_events(self):
"""
Verify successful basket calculation does NOT track any events
TODO: LEARNER 5463
"""
self.mock_user_data(self.user.username)
with mock.patch('ecommerce.extensions.basket.models.track_segment_event') as mock_track:
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
mock_track.assert_not_called()
@mock.patch('ecommerce.extensions.api.v2.views.baskets.BasketCalculateView._calculate_temporary_basket') @mock.patch('ecommerce.extensions.api.v2.views.baskets.BasketCalculateView._calculate_temporary_basket')
@override_flag('disable_calculate_temporary_basket_atomic_transaction', active=True) @override_flag('disable_calculate_temporary_basket_atomic_transaction', active=True)
def test_basket_calculate_anonymous_caching(self, mock_calculate_basket): def test_basket_calculate_anonymous_caching(self, mock_calculate_basket):
......
...@@ -17,13 +17,14 @@ from rest_framework import generics, status ...@@ -17,13 +17,14 @@ from rest_framework import generics, status
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response from rest_framework.response import Response
from ecommerce.cache_utils.utils import TieredCache from ecommerce.cache_utils.utils import RequestCache, TieredCache
from ecommerce.core.utils import get_cache_key from ecommerce.core.utils import get_cache_key
from ecommerce.enterprise.entitlements import get_entitlement_voucher from ecommerce.enterprise.entitlements import get_entitlement_voucher
from ecommerce.extensions.analytics.utils import audit_log from ecommerce.extensions.analytics.utils import audit_log
from ecommerce.extensions.api import data as data_api from ecommerce.extensions.api import data as data_api
from ecommerce.extensions.api import exceptions as api_exceptions from ecommerce.extensions.api import exceptions as api_exceptions
from ecommerce.extensions.api.serializers import OrderSerializer from ecommerce.extensions.api.serializers import OrderSerializer
from ecommerce.extensions.basket.constants import is_calculate_temporary_basket
from ecommerce.extensions.basket.utils import attribute_cookie_data from ecommerce.extensions.basket.utils import attribute_cookie_data
from ecommerce.extensions.checkout.mixins import EdxOrderPlacementMixin from ecommerce.extensions.checkout.mixins import EdxOrderPlacementMixin
from ecommerce.extensions.partner.shortcuts import get_partner_for_site from ecommerce.extensions.partner.shortcuts import get_partner_for_site
...@@ -445,6 +446,8 @@ class BasketCalculateView(generics.GenericAPIView): ...@@ -445,6 +446,8 @@ class BasketCalculateView(generics.GenericAPIView):
'currency': basket.currency 'currency': basket.currency
} }
""" """
RequestCache.set(is_calculate_temporary_basket, True) # TODO: LEARNER 5463
partner = get_partner_for_site(request) partner = get_partner_for_site(request)
skus = request.GET.getlist('sku') skus = request.GET.getlist('sku')
if not skus: if not skus:
......
is_calculate_temporary_basket = "Calculate temporary basket"
...@@ -3,7 +3,9 @@ from django.utils.translation import ugettext_lazy as _ ...@@ -3,7 +3,9 @@ from django.utils.translation import ugettext_lazy as _
from oscar.apps.basket.abstract_models import AbstractBasket from oscar.apps.basket.abstract_models import AbstractBasket
from oscar.core.loading import get_class from oscar.core.loading import get_class
from ecommerce.cache_utils.utils import RequestCache
from ecommerce.extensions.analytics.utils import track_segment_event, translate_basket_line_for_segment from ecommerce.extensions.analytics.utils import track_segment_event, translate_basket_line_for_segment
from ecommerce.extensions.basket.constants import is_calculate_temporary_basket
OrderNumberGenerator = get_class('order.utils', 'OrderNumberGenerator') OrderNumberGenerator = get_class('order.utils', 'OrderNumberGenerator')
Selector = get_class('partner.strategy', 'Selector') Selector = get_class('partner.strategy', 'Selector')
...@@ -49,22 +51,31 @@ class Basket(AbstractBasket): ...@@ -49,22 +51,31 @@ class Basket(AbstractBasket):
def flush(self): def flush(self):
"""Remove all products in basket and fire Segment 'Product Removed' Analytic event for each""" """Remove all products in basket and fire Segment 'Product Removed' Analytic event for each"""
cached_response = RequestCache.get_cached_response(is_calculate_temporary_basket)
if cached_response.is_hit:
# Do not track anything. This is a temporary basket calculation. TODO: LEARNER 5463
return
for line in self.all_lines(): for line in self.all_lines():
# Do not fire events for free items. The volume we see for edX.org leads to a dramatic increase in CPU # Do not fire events for free items. The volume we see for edX.org leads to a dramatic increase in CPU
# usage. Given that orders for free items are ignored, there is no need for these events. # usage. Given that orders for free items are ignored, there is no need for these events.
if line.stockrecord.price_excl_tax > 0: if line.stockrecord.price_excl_tax > 0:
properties = translate_basket_line_for_segment(line) properties = translate_basket_line_for_segment(line)
track_segment_event(self.site, self.owner, 'Product Removed', properties) track_segment_event(self.site, self.owner, 'Product Removed', properties)
# Call flush after we fetch all_lines() which is cleared during flush()
super(Basket, self).flush() # pylint: disable=bad-super-call super(Basket, self).flush() # pylint: disable=bad-super-call
def add_product(self, product, quantity=1, options=None): def add_product(self, product, quantity=1, options=None):
""" Add the indicated product to basket. """
Add the indicated product to basket.
Performs AbstractBasket add_product method and fires Google Analytics 'Product Added' event. Performs AbstractBasket add_product method and fires Google Analytics 'Product Added' event.
""" """
line, created = super(Basket, self).add_product(product, quantity, options) # pylint: disable=bad-super-call line, created = super(Basket, self).add_product(product, quantity, options) # pylint: disable=bad-super-call
cached_response = RequestCache.get_cached_response(is_calculate_temporary_basket)
if cached_response.is_hit:
# Do not track anything. This is a temporary basket calculation. TODO: LEARNER 5463
return line, created
# Do not fire events for free items. The volume we see for edX.org leads to a dramatic increase in CPU # Do not fire events for free items. The volume we see for edX.org leads to a dramatic increase in CPU
# usage. Given that orders for free items are ignored, there is no need for these events. # usage. Given that orders for free items are ignored, there is no need for these events.
...@@ -72,7 +83,6 @@ class Basket(AbstractBasket): ...@@ -72,7 +83,6 @@ class Basket(AbstractBasket):
properties = translate_basket_line_for_segment(line) properties = translate_basket_line_for_segment(line)
properties['cart_id'] = self.id properties['cart_id'] = self.id
track_segment_event(self.site, self.owner, 'Product Added', properties) track_segment_event(self.site, self.owner, 'Product Added', properties)
return line, created return line, created
def clear_vouchers(self): def clear_vouchers(self):
......
...@@ -5,9 +5,12 @@ from oscar.core.loading import get_class, get_model ...@@ -5,9 +5,12 @@ from oscar.core.loading import get_class, get_model
from oscar.test import factories from oscar.test import factories
from analytics import Client from analytics import Client
from ecommerce.cache_utils.utils import RequestCache
from ecommerce.courses.tests.factories import CourseFactory from ecommerce.courses.tests.factories import CourseFactory
from ecommerce.extensions.analytics.utils import parse_tracking_context, translate_basket_line_for_segment from ecommerce.extensions.analytics.utils import parse_tracking_context, translate_basket_line_for_segment
from ecommerce.extensions.api.v2.tests.views.mixins import CatalogMixin from ecommerce.extensions.api.v2.tests.views.mixins import CatalogMixin
from ecommerce.extensions.basket.constants import is_calculate_temporary_basket
from ecommerce.extensions.basket.models import Basket from ecommerce.extensions.basket.models import Basket
from ecommerce.extensions.basket.tests.mixins import BasketMixin from ecommerce.extensions.basket.tests.mixins import BasketMixin
from ecommerce.extensions.test.factories import create_basket from ecommerce.extensions.test.factories import create_basket
...@@ -117,10 +120,7 @@ class BasketTests(CatalogMixin, BasketMixin, TestCase): ...@@ -117,10 +120,7 @@ class BasketTests(CatalogMixin, BasketMixin, TestCase):
""" """
Verify the method fires 'Product Removed' Segment event with the correct information when basket is not empty Verify the method fires 'Product Removed' Segment event with the correct information when basket is not empty
""" """
basket = create_basket(empty=True, site=self.site) basket = self._create_basket_with_product()
course = CourseFactory()
seat = course.create_or_update_seat('verified', True, 100, self.partner)
basket.add_product(seat)
properties = translate_basket_line_for_segment(basket.lines.first()) properties = translate_basket_line_for_segment(basket.lines.first())
user_tracking_id, ga_client_id, lms_ip = parse_tracking_context(basket.owner) user_tracking_id, ga_client_id, lms_ip = parse_tracking_context(basket.owner)
...@@ -135,6 +135,19 @@ class BasketTests(CatalogMixin, BasketMixin, TestCase): ...@@ -135,6 +135,19 @@ class BasketTests(CatalogMixin, BasketMixin, TestCase):
basket.flush() basket.flush()
mock_track.assert_called_once_with(user_tracking_id, 'Product Removed', properties, context=context) mock_track.assert_called_once_with(user_tracking_id, 'Product Removed', properties, context=context)
def test_flush_with_product_is_not_tracked_for_temporary_basket_calculation(self):
"""
Verify the method does NOT fire 'Product Removed' Segment for temporary basket calculation
TODO: LEARNER 5463
"""
basket = self._create_basket_with_product()
RequestCache.set(is_calculate_temporary_basket, True)
with mock.patch.object(Client, 'track') as mock_track:
basket.flush()
mock_track.assert_not_called()
def test_flush_without_product(self): def test_flush_without_product(self):
""" Verify the method does not fireSegment event when basket is empty """ """ Verify the method does not fireSegment event when basket is empty """
basket = create_basket(empty=True, site=self.site) basket = create_basket(empty=True, site=self.site)
...@@ -154,6 +167,22 @@ class BasketTests(CatalogMixin, BasketMixin, TestCase): ...@@ -154,6 +167,22 @@ class BasketTests(CatalogMixin, BasketMixin, TestCase):
properties['cart_id'] = basket.id properties['cart_id'] = basket.id
mock_track.assert_called_once_with(basket.site, basket.owner, 'Product Added', properties) mock_track.assert_called_once_with(basket.site, basket.owner, 'Product Added', properties)
def test_add_product_not_tracked_for_temporary_basket_calculation(self):
"""
Verify the method does NOT fire Product Added analytic event when a product is added to the basket
TODO: LEARNER 5463
"""
course = CourseFactory()
basket = create_basket(empty=True)
seat = course.create_or_update_seat('verified', True, 100, self.partner)
RequestCache.set(is_calculate_temporary_basket, True)
with mock.patch('ecommerce.extensions.basket.models.track_segment_event') as mock_track:
basket.add_product(seat)
properties = translate_basket_line_for_segment(basket.lines.first())
properties['cart_id'] = basket.id
mock_track.assert_not_called()
def test_product_events_with_free_items(self): def test_product_events_with_free_items(self):
""" Product Added/Removed events should not be fired for free products. """ """ Product Added/Removed events should not be fired for free products. """
course = CourseFactory() course = CourseFactory()
...@@ -164,3 +193,10 @@ class BasketTests(CatalogMixin, BasketMixin, TestCase): ...@@ -164,3 +193,10 @@ class BasketTests(CatalogMixin, BasketMixin, TestCase):
basket.add_product(seat) basket.add_product(seat)
basket.flush() basket.flush()
self.assertEqual(mock_track.call_count, 0) self.assertEqual(mock_track.call_count, 0)
def _create_basket_with_product(self):
basket = create_basket(empty=True, site=self.site)
course = CourseFactory()
seat = course.create_or_update_seat('verified', True, 100, self.partner)
basket.add_product(seat)
return basket
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