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
9a094c9a
Commit
9a094c9a
authored
May 20, 2016
by
Ayub khan
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #720 from edx/ECOM-4312
ECOM-4312 Check added to prevent multiple order issue.
parents
96fcf292
4a95a746
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
101 additions
and
4 deletions
+101
-4
ecommerce/core/url_utils.py
+5
-0
ecommerce/extensions/basket/tests/test_views.py
+60
-0
ecommerce/extensions/basket/views.py
+36
-4
No files found.
ecommerce/core/url_utils.py
View file @
9a094c9a
...
...
@@ -33,6 +33,11 @@ def get_lms_enrollment_api_url():
return
get_lms_url
(
'/api/enrollment/v1/enrollment'
)
def
get_lms_enrollment_base_api_url
():
""" Returns the Base lms enrollment api url."""
return
get_lms_url
(
'/api/enrollment/v1'
)
def
get_lms_heartbeat_url
():
return
get_lms_url
(
'/heartbeat'
)
...
...
ecommerce/extensions/basket/tests/test_views.py
View file @
9a094c9a
import
datetime
import
hashlib
import
json
import
ddt
from
django.conf
import
settings
...
...
@@ -16,6 +17,7 @@ from slumber.exceptions import SlumberBaseException
from
testfixtures
import
LogCapture
from
ecommerce.core.constants
import
ENROLLMENT_CODE_PRODUCT_CLASS_NAME
,
ENROLLMENT_CODE_SWITCH
from
ecommerce.core.url_utils
import
get_lms_enrollment_api_url
from
ecommerce.core.models
import
SiteConfiguration
from
ecommerce.core.tests
import
toggle_switch
from
ecommerce.core.url_utils
import
get_lms_url
...
...
@@ -39,6 +41,7 @@ StockRecord = get_model('partner', 'StockRecord')
COUPON_CODE
=
'COUPONTEST'
@ddt.ddt
class
BasketSingleItemViewTests
(
CouponMixin
,
CourseCatalogTestMixin
,
LmsApiMockMixin
,
TestCase
):
""" BasketSingleItemView view tests. """
path
=
reverse
(
'basket:single-item'
)
...
...
@@ -55,6 +58,29 @@ class BasketSingleItemViewTests(CouponMixin, CourseCatalogTestMixin, LmsApiMockM
self
.
catalog
=
Catalog
.
objects
.
create
(
partner
=
self
.
partner
)
self
.
catalog
.
stock_records
.
add
(
self
.
stock_record
)
def
mock_enrollment_api_success
(
self
,
course_id
,
mode
=
'audit'
):
""" Returns a successful response indicating self.user is enrolled in the specified course mode. """
self
.
assertTrue
(
httpretty
.
is_enabled
())
url
=
'{host}/{username},{course_id}'
.
format
(
host
=
get_lms_enrollment_api_url
(),
username
=
self
.
user
.
username
,
course_id
=
course_id
)
httpretty
.
register_uri
(
httpretty
.
GET
,
url
,
body
=
json
.
dumps
({
'mode'
:
mode
}),
content_type
=
'application/json'
)
def
mock_enrollment_api_error
(
self
,
error
):
""" Mock Enrollment api call which raises error when called """
self
.
assertTrue
(
httpretty
.
is_enabled
())
def
callback
(
request
,
uri
,
headers
):
# pylint: disable=unused-argument
raise
error
url
=
'{host}/{username},{course_id}'
.
format
(
host
=
get_lms_enrollment_api_url
(),
username
=
self
.
user
.
username
,
course_id
=
self
.
course
.
id
)
httpretty
.
register_uri
(
httpretty
.
GET
,
url
,
body
=
callback
,
content_type
=
'application/json'
)
def
test_login_required
(
self
):
""" The view should redirect to login page if the user is not logged in. """
self
.
client
.
logout
()
...
...
@@ -78,8 +104,10 @@ class BasketSingleItemViewTests(CouponMixin, CourseCatalogTestMixin, LmsApiMockM
self
.
assertEqual
(
response
.
status_code
,
400
)
self
.
assertEqual
(
response
.
content
,
expected_content
)
@httpretty.activate
def
test_unavailable_product
(
self
):
""" The view should return HTTP 400 if the product is not available for purchase. """
self
.
mock_enrollment_api_success
(
self
.
course
.
id
)
product
=
self
.
stock_record
.
product
product
.
expires
=
pytz
.
utc
.
localize
(
datetime
.
datetime
.
min
)
product
.
save
()
...
...
@@ -96,6 +124,7 @@ class BasketSingleItemViewTests(CouponMixin, CourseCatalogTestMixin, LmsApiMockM
"""
Verify the view redirects to the basket summary page, and that the user's basket is prepared for checkout.
"""
self
.
mock_enrollment_api_success
(
self
.
course
.
id
)
self
.
create_coupon
(
catalog
=
self
.
catalog
,
code
=
COUPON_CODE
,
benefit_value
=
5
)
self
.
mock_course_api_response
(
course
=
self
.
course
)
...
...
@@ -111,6 +140,37 @@ class BasketSingleItemViewTests(CouponMixin, CourseCatalogTestMixin, LmsApiMockM
self
.
assertTrue
(
basket
.
contains_a_voucher
)
self
.
assertEqual
(
basket
.
lines
.
first
()
.
product
,
self
.
stock_record
.
product
)
@httpretty.activate
@ddt.data
((
'verified'
,
False
),
(
'professional'
,
True
),
(
'no-id-professional'
,
False
))
@ddt.unpack
def
test_already_verified_student
(
self
,
mode
,
id_verification
):
"""
Verify the view return HTTP 400 if the student is already enrolled as verified student in the course
"""
course
=
CourseFactory
()
self
.
mock_enrollment_api_success
(
course
.
id
,
mode
=
mode
)
product
=
course
.
create_or_update_seat
(
mode
,
id_verification
,
0
,
self
.
partner
)
stock_record
=
StockRecordFactory
(
product
=
product
,
partner
=
self
.
partner
)
catalog
=
Catalog
.
objects
.
create
(
partner
=
self
.
partner
)
catalog
.
stock_records
.
add
(
stock_record
)
url
=
'{path}?sku={sku}'
.
format
(
path
=
self
.
path
,
sku
=
stock_record
.
partner_sku
)
expected_content
=
'You are already enrolled in {product}.'
.
format
(
product
=
product
.
course
.
name
)
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
400
)
self
.
assertEqual
(
response
.
content
,
expected_content
)
@httpretty.activate
@ddt.data
(
ConnectionError
,
SlumberBaseException
,
Timeout
)
def
test_enrollment_api_failure
(
self
,
error
):
"""
Verify the view returns HTTP status 400 if the Enrollment API is not available.
"""
self
.
mock_enrollment_api_error
(
error
)
url
=
'{path}?sku={sku}'
.
format
(
path
=
self
.
path
,
sku
=
self
.
stock_record
.
partner_sku
)
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
400
)
@httpretty.activate
@ddt.ddt
...
...
ecommerce/extensions/basket/views.py
View file @
9a094c9a
...
...
@@ -15,8 +15,9 @@ from edx_rest_api_client.client import EdxRestApiClient
from
slumber.exceptions
import
SlumberBaseException
from
ecommerce.core.constants
import
ENROLLMENT_CODE_PRODUCT_CLASS_NAME
,
SEAT_PRODUCT_CLASS_NAME
from
ecommerce.core.url_utils
import
get_lms_url
from
ecommerce.core.url_utils
import
get_lms_url
,
get_lms_enrollment_base_api_url
from
ecommerce.coupons.views
import
get_voucher_from_code
from
ecommerce.courses.utils
import
mode_for_seat
from
ecommerce.extensions.analytics.utils
import
prepare_analytics_data
from
ecommerce.extensions.basket.utils
import
get_certificate_type_display_value
,
prepare_basket
from
ecommerce.extensions.offer.utils
import
format_benefit_value
...
...
@@ -48,12 +49,43 @@ class BasketSingleItemView(View):
try
:
product
=
StockRecord
.
objects
.
get
(
partner
=
partner
,
partner_sku
=
sku
)
.
product
course_key
=
product
.
attr
.
course_key
api
=
EdxRestApiClient
(
get_lms_enrollment_base_api_url
(),
oauth_access_token
=
request
.
user
.
access_token
,
append_slash
=
False
)
logger
.
debug
(
'Getting enrollment information for [
%
s] in [
%
s].'
,
request
.
user
.
username
,
course_key
)
status
=
api
.
enrollment
(
','
.
join
([
request
.
user
.
username
,
course_key
]))
.
get
()
username
=
request
.
user
.
username
seat_type
=
mode_for_seat
(
product
)
if
status
and
status
.
get
(
'mode'
)
==
seat_type
:
logger
.
warning
(
'User [
%
s] attempted to repurchase the [
%
s] seat of course [
%
s]'
,
username
,
seat_type
,
course_key
)
return
HttpResponseBadRequest
(
_
(
'You are already enrolled in {course}.'
)
.
format
(
course
=
product
.
course
.
name
))
except
StockRecord
.
DoesNotExist
:
return
HttpResponseBadRequest
(
_
(
'SKU [{sku}] does not exist.'
.
format
(
sku
=
sku
)))
return
HttpResponseBadRequest
(
_
(
'SKU [{sku}] does not exist.'
)
.
format
(
sku
=
sku
))
except
(
ConnectionError
,
SlumberBaseException
,
Timeout
)
as
ex
:
logger
.
exception
(
'Failed to retrieve enrollment details for [
%
s] in course [
%
s], Because of [
%
s]'
,
request
.
user
.
username
,
course_key
,
ex
,
)
return
HttpResponseBadRequest
(
_
(
'An error occurred while retrieving enrollment details. Please try again.'
))
purchase_info
=
request
.
strategy
.
fetch_for_product
(
product
)
if
not
purchase_info
.
availability
.
is_available_to_buy
:
return
HttpResponseBadRequest
(
_
(
'Product [{product}] not available to buy.'
.
format
(
product
=
product
.
title
)
))
return
HttpResponseBadRequest
(
_
(
'Product [{product}] not available to buy.'
)
.
format
(
product
=
product
.
title
))
prepare_basket
(
request
,
product
,
voucher
)
return
HttpResponseRedirect
(
reverse
(
'basket:summary'
),
status
=
303
)
...
...
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