Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
ecommerce
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
ecommerce
Commits
4ecc1867
Commit
4ecc1867
authored
Aug 13, 2015
by
Clinton Blackburn
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #277 from edx/ga-update
Sending Course ID to Segment/Google Analytics
parents
0ae5322c
97395ada
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
23 additions
and
84 deletions
+23
-84
ecommerce/extensions/checkout/signals.py
+3
-2
ecommerce/extensions/refund/signals.py
+1
-1
ecommerce/extensions/refund/tests/factories.py
+1
-62
ecommerce/extensions/refund/tests/mixins.py
+7
-8
ecommerce/extensions/refund/tests/test_api.py
+5
-5
ecommerce/extensions/refund/tests/test_signals.py
+4
-4
ecommerce/tests/mixins.py
+2
-2
No files found.
ecommerce/extensions/checkout/signals.py
View file @
4ecc1867
...
@@ -12,8 +12,9 @@ from ecommerce.settings.base import get_lms_url
...
@@ -12,8 +12,9 @@ from ecommerce.settings.base import get_lms_url
from
oscar.core.loading
import
get_class
from
oscar.core.loading
import
get_class
post_checkout
=
get_class
(
'checkout.signals'
,
'post_checkout'
)
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
post_checkout
=
get_class
(
'checkout.signals'
,
'post_checkout'
)
# Number of orders currently supported for the email notifications
# Number of orders currently supported for the email notifications
ORDER_LINE_COUNT
=
1
ORDER_LINE_COUNT
=
1
...
@@ -42,7 +43,7 @@ def track_completed_order(sender, order=None, **kwargs): # pylint: disable=unus
...
@@ -42,7 +43,7 @@ def track_completed_order(sender, order=None, **kwargs): # pylint: disable=unus
# products other than courses, and will need to change in the future.
# products other than courses, and will need to change in the future.
'id'
:
line
.
partner_sku
,
'id'
:
line
.
partner_sku
,
'sku'
:
mode_for_seat
(
line
.
product
),
'sku'
:
mode_for_seat
(
line
.
product
),
'name'
:
line
.
product
.
title
,
'name'
:
line
.
product
.
course
.
id
,
'price'
:
str
(
line
.
line_price_excl_tax
),
'price'
:
str
(
line
.
line_price_excl_tax
),
'quantity'
:
line
.
quantity
,
'quantity'
:
line
.
quantity
,
'category'
:
line
.
product
.
get_product_class
()
.
name
,
'category'
:
line
.
product
.
get_product_class
()
.
name
,
...
...
ecommerce/extensions/refund/signals.py
View file @
4ecc1867
...
@@ -36,7 +36,7 @@ def track_completed_refund(sender, refund=None, **kwargs): # pylint: disable=un
...
@@ -36,7 +36,7 @@ def track_completed_refund(sender, refund=None, **kwargs): # pylint: disable=un
# products other than courses, and will need to change in the future.
# products other than courses, and will need to change in the future.
'id'
:
line
.
order_line
.
partner_sku
,
'id'
:
line
.
order_line
.
partner_sku
,
'sku'
:
mode_for_seat
(
line
.
order_line
.
product
),
'sku'
:
mode_for_seat
(
line
.
order_line
.
product
),
'name'
:
line
.
order_line
.
product
.
title
,
'name'
:
line
.
order_line
.
product
.
course
.
id
,
'price'
:
str
(
line
.
line_credit_excl_tax
),
'price'
:
str
(
line
.
line_credit_excl_tax
),
'quantity'
:
-
1
*
line
.
quantity
,
'quantity'
:
-
1
*
line
.
quantity
,
'category'
:
line
.
order_line
.
product
.
get_product_class
()
.
name
,
'category'
:
line
.
order_line
.
product
.
get_product_class
()
.
name
,
...
...
ecommerce/extensions/refund/tests/factories.py
View file @
4ecc1867
from
decimal
import
Decimal
from
decimal
import
Decimal
from
django.conf
import
settings
from
django.conf
import
settings
from
django.utils.text
import
slugify
import
factory
import
factory
from
oscar.core.loading
import
get_model
from
oscar.core.loading
import
get_model
from
oscar.test
import
factories
from
oscar.test
import
factories
from
oscar.test.newfactories
import
UserFactory
from
oscar.test.newfactories
import
UserFactory
from
ecommerce.courses.models
import
Course
from
ecommerce.extensions.refund.status
import
REFUND
,
REFUND_LINE
from
ecommerce.extensions.refund.status
import
REFUND
,
REFUND_LINE
...
@@ -28,7 +26,7 @@ class RefundFactory(factory.DjangoModelFactory):
...
@@ -28,7 +26,7 @@ class RefundFactory(factory.DjangoModelFactory):
return
factories
.
create_order
(
user
=
self
.
user
)
return
factories
.
create_order
(
user
=
self
.
user
)
@factory.post_generation
@factory.post_generation
def
create_lines
(
self
,
create
,
extracted
,
**
kwargs
):
# pylint: disable=unused-argument
def
create_lines
(
self
,
create
,
extracted
,
**
kwargs
):
# pylint: disable=unused-argument
if
not
create
:
if
not
create
:
return
return
...
@@ -54,62 +52,3 @@ class RefundLineFactory(factory.DjangoModelFactory):
...
@@ -54,62 +52,3 @@ class RefundLineFactory(factory.DjangoModelFactory):
class
Meta
(
object
):
class
Meta
(
object
):
model
=
get_model
(
'refund'
,
'RefundLine'
)
model
=
get_model
(
'refund'
,
'RefundLine'
)
class
CourseFactory
(
object
):
def
__init__
(
self
,
course_id
,
course_name
):
self
.
course_name
=
course_name
self
.
course_id
=
course_id
self
.
modes
=
{}
self
.
partner
,
_created
=
Partner
.
objects
.
get_or_create
(
name
=
'edX'
)
def
_get_parent_seat_product
(
self
):
seat
,
created
=
ProductClass
.
objects
.
get_or_create
(
slug
=
'seat'
,
defaults
=
{
'track_stock'
:
False
,
'requires_shipping'
:
False
,
'name'
:
'Seat'
})
if
created
:
ProductAttribute
.
objects
.
create
(
product_class
=
seat
,
name
=
'course_key'
,
code
=
'course_key'
,
type
=
'text'
,
required
=
True
)
ProductAttribute
.
objects
.
create
(
product_class
=
seat
,
name
=
'id_verification_required'
,
code
=
'id_verification_required'
,
type
=
'boolean'
,
required
=
False
)
ProductAttribute
.
objects
.
create
(
product_class
=
seat
,
name
=
'certificate_type'
,
code
=
'certificate_type'
,
type
=
'text'
,
required
=
False
)
slug
=
slugify
(
self
.
course_name
)
title
=
u'Seat in {}'
.
format
(
self
.
course_name
)
parent_product
,
created
=
Product
.
objects
.
get_or_create
(
product_class
=
seat
,
slug
=
slug
,
structure
=
'parent'
,
defaults
=
{
'title'
:
title
})
if
created
:
parent_product
.
attr
.
course_key
=
self
.
course_id
parent_product
.
save
()
return
parent_product
def
add_mode
(
self
,
name
,
price
,
id_verification_required
=
False
):
parent_product
=
self
.
_get_parent_seat_product
()
certificate_type
=
Course
.
certificate_type_for_mode
(
name
)
title
=
u'{certificate_type} Seat in {course_name}'
.
format
(
certificate_type
=
certificate_type
,
course_name
=
self
.
course_name
)
slug
=
slugify
(
u'{course_name}-seat-{certificate_type}'
.
format
(
course_name
=
self
.
course_name
,
certificate_type
=
certificate_type
))
child_product
,
created
=
Product
.
objects
.
get_or_create
(
parent
=
parent_product
,
title
=
title
,
slug
=
slug
,
structure
=
'child'
)
if
created
:
child_product
.
attr
.
course_key
=
self
.
course_id
child_product
.
attr
.
certificate_type
=
certificate_type
child_product
.
attr
.
id_verification_required
=
id_verification_required
child_product
.
save
()
child_product
.
stockrecords
.
create
(
partner
=
self
.
partner
,
partner_sku
=
slug
,
num_in_stock
=
None
,
price_currency
=
settings
.
OSCAR_DEFAULT_CURRENCY
,
price_excl_tax
=
price
)
self
.
modes
[
name
]
=
child_product
return
child_product
ecommerce/extensions/refund/tests/mixins.py
View file @
4ecc1867
# coding=utf-8
# coding=utf-8
from
decimal
import
Decimal
from
django.conf
import
settings
from
django.conf
import
settings
from
django.test
import
override_settings
from
django.test
import
override_settings
...
@@ -9,11 +8,12 @@ from oscar.core.loading import get_model, get_class
...
@@ -9,11 +8,12 @@ from oscar.core.loading import get_model, get_class
from
oscar.test.factories
import
create_order
from
oscar.test.factories
import
create_order
from
oscar.test.newfactories
import
BasketFactory
from
oscar.test.newfactories
import
BasketFactory
from
ecommerce.courses.models
import
Course
from
ecommerce.extensions.catalogue.tests.mixins
import
CourseCatalogTestMixin
from
ecommerce.extensions.fulfillment.status
import
ORDER
from
ecommerce.extensions.fulfillment.status
import
ORDER
from
ecommerce.extensions.payment.tests.processors
import
DummyProcessor
from
ecommerce.extensions.payment.tests.processors
import
DummyProcessor
from
ecommerce.extensions.refund.status
import
REFUND
,
REFUND_LINE
from
ecommerce.extensions.refund.status
import
REFUND
,
REFUND_LINE
from
ecommerce.extensions.refund.tests.factories
import
CourseFactory
,
RefundFactory
from
ecommerce.extensions.refund.tests.factories
import
RefundFactory
post_refund
=
get_class
(
'refund.signals'
,
'post_refund'
)
post_refund
=
get_class
(
'refund.signals'
,
'post_refund'
)
Refund
=
get_model
(
'refund'
,
'Refund'
)
Refund
=
get_model
(
'refund'
,
'Refund'
)
...
@@ -21,13 +21,12 @@ Source = get_model('payment', 'Source')
...
@@ -21,13 +21,12 @@ Source = get_model('payment', 'Source')
SourceType
=
get_model
(
'payment'
,
'SourceType'
)
SourceType
=
get_model
(
'payment'
,
'SourceType'
)
class
RefundTestMixin
(
object
):
class
RefundTestMixin
(
CourseCatalogTestMixin
):
def
setUp
(
self
):
def
setUp
(
self
):
super
(
RefundTestMixin
,
self
)
.
setUp
()
super
(
RefundTestMixin
,
self
)
.
setUp
()
self
.
course_id
=
u'edX/DemoX/Demo_Course'
self
.
course
,
__
=
Course
.
objects
.
get_or_create
(
id
=
u'edX/DemoX/Demo_Course'
,
name
=
u'edX Demó Course'
)
self
.
course
=
CourseFactory
(
self
.
course_id
,
u'edX Demó Course'
)
self
.
honor_product
=
self
.
course
.
create_or_update_seat
(
'honor'
,
False
,
0
)
self
.
honor_product
=
self
.
course
.
add_mode
(
'honor'
,
0
)
self
.
verified_product
=
self
.
course
.
create_or_update_seat
(
'verified'
,
True
,
10
)
self
.
verified_product
=
self
.
course
.
add_mode
(
'verified'
,
Decimal
(
10.00
),
id_verification_required
=
True
)
def
create_order
(
self
,
user
=
None
,
multiple_lines
=
False
,
free
=
False
):
def
create_order
(
self
,
user
=
None
,
multiple_lines
=
False
,
free
=
False
):
user
=
user
or
self
.
user
user
=
user
or
self
.
user
...
...
ecommerce/extensions/refund/tests/test_api.py
View file @
4ecc1867
...
@@ -32,7 +32,7 @@ class ApiTests(RefundTestMixin, TestCase):
...
@@ -32,7 +32,7 @@ class ApiTests(RefundTestMixin, TestCase):
order
=
self
.
create_order
()
order
=
self
.
create_order
()
self
.
assertTrue
(
self
.
user
.
orders
.
exists
())
self
.
assertTrue
(
self
.
user
.
orders
.
exists
())
actual
=
find_orders_associated_with_course
(
self
.
user
,
self
.
course
_
id
)
actual
=
find_orders_associated_with_course
(
self
.
user
,
self
.
course
.
id
)
self
.
assertEqual
(
actual
,
[
order
])
self
.
assertEqual
(
actual
,
[
order
])
@ddt.data
(
''
,
' '
,
None
)
@ddt.data
(
''
,
' '
,
None
)
...
@@ -44,7 +44,7 @@ class ApiTests(RefundTestMixin, TestCase):
...
@@ -44,7 +44,7 @@ class ApiTests(RefundTestMixin, TestCase):
""" An empty list should be returned if the user has never placed an order. """
""" An empty list should be returned if the user has never placed an order. """
self
.
assertFalse
(
self
.
user
.
orders
.
exists
())
self
.
assertFalse
(
self
.
user
.
orders
.
exists
())
actual
=
find_orders_associated_with_course
(
self
.
user
,
self
.
course
_
id
)
actual
=
find_orders_associated_with_course
(
self
.
user
,
self
.
course
.
id
)
self
.
assertEqual
(
actual
,
[])
self
.
assertEqual
(
actual
,
[])
@ddt.data
(
ORDER
.
OPEN
,
ORDER
.
FULFILLMENT_ERROR
)
@ddt.data
(
ORDER
.
OPEN
,
ORDER
.
FULFILLMENT_ERROR
)
...
@@ -54,7 +54,7 @@ class ApiTests(RefundTestMixin, TestCase):
...
@@ -54,7 +54,7 @@ class ApiTests(RefundTestMixin, TestCase):
order
.
status
=
status
order
.
status
=
status
order
.
save
()
order
.
save
()
actual
=
find_orders_associated_with_course
(
self
.
user
,
self
.
course
_
id
)
actual
=
find_orders_associated_with_course
(
self
.
user
,
self
.
course
.
id
)
self
.
assertEqual
(
actual
,
[])
self
.
assertEqual
(
actual
,
[])
# TODO Implement this when we begin storing the verification close date.
# TODO Implement this when we begin storing the verification close date.
...
@@ -67,7 +67,7 @@ class ApiTests(RefundTestMixin, TestCase):
...
@@ -67,7 +67,7 @@ class ApiTests(RefundTestMixin, TestCase):
def
test_create_refunds
(
self
):
def
test_create_refunds
(
self
):
""" The method should create refunds for orders/lines that have not been refunded. """
""" The method should create refunds for orders/lines that have not been refunded. """
order
=
self
.
create_order
()
order
=
self
.
create_order
()
actual
=
create_refunds
([
order
],
self
.
course
_
id
)
actual
=
create_refunds
([
order
],
self
.
course
.
id
)
refund
=
Refund
.
objects
.
get
(
order
=
order
)
refund
=
Refund
.
objects
.
get
(
order
=
order
)
self
.
assertEqual
(
actual
,
[
refund
])
self
.
assertEqual
(
actual
,
[
refund
])
self
.
assert_refund_matches_order
(
refund
,
order
)
self
.
assert_refund_matches_order
(
refund
,
order
)
...
@@ -77,5 +77,5 @@ class ApiTests(RefundTestMixin, TestCase):
...
@@ -77,5 +77,5 @@ class ApiTests(RefundTestMixin, TestCase):
order
=
self
.
create_order
()
order
=
self
.
create_order
()
RefundLineFactory
(
order_line
=
order
.
lines
.
first
())
RefundLineFactory
(
order_line
=
order
.
lines
.
first
())
actual
=
create_refunds
([
order
],
self
.
course
_
id
)
actual
=
create_refunds
([
order
],
self
.
course
.
id
)
self
.
assertEqual
(
actual
,
[])
self
.
assertEqual
(
actual
,
[])
ecommerce/extensions/refund/tests/test_signals.py
View file @
4ecc1867
...
@@ -2,7 +2,6 @@ from django.test import TestCase, override_settings
...
@@ -2,7 +2,6 @@ from django.test import TestCase, override_settings
from
mock
import
patch
from
mock
import
patch
from
oscar.test.newfactories
import
UserFactory
from
oscar.test.newfactories
import
UserFactory
from
ecommerce.extensions.catalogue.tests.mixins
import
CourseCatalogTestMixin
from
ecommerce.extensions.refund.api
import
create_refunds
from
ecommerce.extensions.refund.api
import
create_refunds
from
ecommerce.extensions.refund.tests.mixins
import
RefundTestMixin
from
ecommerce.extensions.refund.tests.mixins
import
RefundTestMixin
from
ecommerce.tests.mixins
import
BusinessIntelligenceMixin
from
ecommerce.tests.mixins
import
BusinessIntelligenceMixin
...
@@ -10,14 +9,15 @@ from ecommerce.tests.mixins import BusinessIntelligenceMixin
...
@@ -10,14 +9,15 @@ from ecommerce.tests.mixins import BusinessIntelligenceMixin
@override_settings
(
SEGMENT_KEY
=
'dummy-key'
)
@override_settings
(
SEGMENT_KEY
=
'dummy-key'
)
@patch
(
'analytics.track'
)
@patch
(
'analytics.track'
)
class
RefundTrackingTests
(
BusinessIntelligenceMixin
,
CourseCatalogTestMixin
,
RefundTestMixin
,
TestCase
):
class
RefundTrackingTests
(
BusinessIntelligenceMixin
,
RefundTestMixin
,
TestCase
):
"""Tests verifying the behavior of refund tracking."""
"""Tests verifying the behavior of refund tracking."""
def
setUp
(
self
):
def
setUp
(
self
):
super
(
RefundTrackingTests
,
self
)
.
setUp
()
super
(
RefundTrackingTests
,
self
)
.
setUp
()
self
.
user
=
UserFactory
()
self
.
user
=
UserFactory
()
self
.
order
=
self
.
create_order
()
self
.
order
=
self
.
create_order
()
self
.
refund
=
create_refunds
([
self
.
order
],
self
.
course
_
id
)[
0
]
self
.
refund
=
create_refunds
([
self
.
order
],
self
.
course
.
id
)[
0
]
def
test_successful_refund_tracking
(
self
,
mock_track
):
def
test_successful_refund_tracking
(
self
,
mock_track
):
"""Verify that a successfully placed refund is tracked when Segment is enabled."""
"""Verify that a successfully placed refund is tracked when Segment is enabled."""
...
@@ -48,7 +48,7 @@ class RefundTrackingTests(BusinessIntelligenceMixin, CourseCatalogTestMixin, Ref
...
@@ -48,7 +48,7 @@ class RefundTrackingTests(BusinessIntelligenceMixin, CourseCatalogTestMixin, Ref
to a total credit of 0.
to a total credit of 0.
"""
"""
order
=
self
.
create_order
(
free
=
True
)
order
=
self
.
create_order
(
free
=
True
)
create_refunds
([
order
],
self
.
course
_
id
)
create_refunds
([
order
],
self
.
course
.
id
)
# Verify that no business intelligence event was emitted. Refunds corresponding
# Verify that no business intelligence event was emitted. Refunds corresponding
# to a total credit of 0 are automatically approved upon creation.
# to a total credit of 0 are automatically approved upon creation.
...
...
ecommerce/tests/mixins.py
View file @
4ecc1867
...
@@ -199,7 +199,7 @@ class BusinessIntelligenceMixin(object):
...
@@ -199,7 +199,7 @@ class BusinessIntelligenceMixin(object):
for
line
in
lines
:
for
line
in
lines
:
tracked_product
=
tracked_products_dict
.
get
(
line
.
partner_sku
)
tracked_product
=
tracked_products_dict
.
get
(
line
.
partner_sku
)
self
.
assertIsNotNone
(
tracked_product
)
self
.
assertIsNotNone
(
tracked_product
)
self
.
assertEqual
(
line
.
product
.
title
,
tracked_product
[
'name'
])
self
.
assertEqual
(
line
.
product
.
course
.
id
,
tracked_product
[
'name'
])
self
.
assertEqual
(
str
(
line
.
line_price_excl_tax
),
tracked_product
[
'price'
])
self
.
assertEqual
(
str
(
line
.
line_price_excl_tax
),
tracked_product
[
'price'
])
self
.
assertEqual
(
line
.
quantity
,
tracked_product
[
'quantity'
])
self
.
assertEqual
(
line
.
quantity
,
tracked_product
[
'quantity'
])
self
.
assertEqual
(
mode_for_seat
(
line
.
product
),
tracked_product
[
'sku'
])
self
.
assertEqual
(
mode_for_seat
(
line
.
product
),
tracked_product
[
'sku'
])
...
@@ -210,7 +210,7 @@ class BusinessIntelligenceMixin(object):
...
@@ -210,7 +210,7 @@ class BusinessIntelligenceMixin(object):
for
line
in
lines
:
for
line
in
lines
:
tracked_product
=
tracked_products_dict
.
get
(
line
.
order_line
.
partner_sku
)
tracked_product
=
tracked_products_dict
.
get
(
line
.
order_line
.
partner_sku
)
self
.
assertIsNotNone
(
tracked_product
)
self
.
assertIsNotNone
(
tracked_product
)
self
.
assertEqual
(
line
.
order_line
.
product
.
title
,
tracked_product
[
'name'
])
self
.
assertEqual
(
line
.
order_line
.
product
.
course
.
id
,
tracked_product
[
'name'
])
self
.
assertEqual
(
str
(
line
.
line_credit_excl_tax
),
tracked_product
[
'price'
])
self
.
assertEqual
(
str
(
line
.
line_credit_excl_tax
),
tracked_product
[
'price'
])
self
.
assertEqual
(
-
1
*
line
.
quantity
,
tracked_product
[
'quantity'
])
self
.
assertEqual
(
-
1
*
line
.
quantity
,
tracked_product
[
'quantity'
])
self
.
assertEqual
(
mode_for_seat
(
line
.
order_line
.
product
),
tracked_product
[
'sku'
])
self
.
assertEqual
(
mode_for_seat
(
line
.
order_line
.
product
),
tracked_product
[
'sku'
])
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment