Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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
edx-platform
Commits
0fece869
Commit
0fece869
authored
Oct 28, 2015
by
Clinton Blackburn
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #10349 from edx/multi-tenancy/update-receipt-page
Updated receipt page to use order endpoint
parents
de7113a1
9bb3f703
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
99 additions
and
10 deletions
+99
-10
lms/djangoapps/commerce/api/v0/urls.py
+1
-1
lms/djangoapps/commerce/api/v1/tests/test_views.py
+41
-0
lms/djangoapps/commerce/api/v1/urls.py
+6
-2
lms/djangoapps/commerce/api/v1/views.py
+20
-1
lms/djangoapps/commerce/tests/mocks.py
+14
-0
lms/static/js/commerce/views/receipt_view.js
+17
-6
No files found.
lms/djangoapps/commerce/api/v0/urls.py
View file @
0fece869
...
@@ -7,7 +7,7 @@ from commerce.api.v0 import views
...
@@ -7,7 +7,7 @@ from commerce.api.v0 import views
BASKET_URLS
=
patterns
(
BASKET_URLS
=
patterns
(
''
,
''
,
url
(
r'^$'
,
views
.
BasketsView
.
as_view
(),
name
=
'create'
),
url
(
r'^$'
,
views
.
BasketsView
.
as_view
(),
name
=
'create'
),
url
(
r'^
{}/order/$'
.
format
(
r'(?P<basket_id>[\w]+)'
)
,
views
.
BasketOrderView
.
as_view
(),
name
=
'retrieve_order'
),
url
(
r'^
(?P<basket_id>[\w]+)/order/$'
,
views
.
BasketOrderView
.
as_view
(),
name
=
'retrieve_order'
),
)
)
urlpatterns
=
patterns
(
urlpatterns
=
patterns
(
...
...
lms/djangoapps/commerce/api/v1/tests/test_views.py
View file @
0fece869
...
@@ -7,13 +7,19 @@ import ddt
...
@@ -7,13 +7,19 @@ import ddt
from
django.conf
import
settings
from
django.conf
import
settings
from
django.contrib.auth.models
import
Permission
from
django.contrib.auth.models
import
Permission
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
django.test
import
TestCase
from
django.test.utils
import
override_settings
from
django.test.utils
import
override_settings
from
edx_rest_api_client
import
exceptions
from
flaky
import
flaky
from
flaky
import
flaky
from
nose.plugins.attrib
import
attr
import
pytz
import
pytz
from
rest_framework.utils.encoders
import
JSONEncoder
from
rest_framework.utils.encoders
import
JSONEncoder
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
commerce.tests
import
TEST_API_URL
,
TEST_API_SIGNING_KEY
from
commerce.tests.mocks
import
mock_order_endpoint
from
commerce.tests.test_views
import
UserMixin
from
course_modes.models
import
CourseMode
from
course_modes.models
import
CourseMode
from
student.tests.factories
import
UserFactory
from
student.tests.factories
import
UserFactory
from
verify_student.models
import
VerificationDeadline
from
verify_student.models
import
VerificationDeadline
...
@@ -307,3 +313,38 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
...
@@ -307,3 +313,38 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
]
]
}
}
self
.
assertDictEqual
(
expected_dict
,
json
.
loads
(
response
.
content
))
self
.
assertDictEqual
(
expected_dict
,
json
.
loads
(
response
.
content
))
@attr
(
'shard_1'
)
@override_settings
(
ECOMMERCE_API_URL
=
TEST_API_URL
,
ECOMMERCE_API_SIGNING_KEY
=
TEST_API_SIGNING_KEY
)
class
OrderViewTests
(
UserMixin
,
TestCase
):
""" Tests for the basket order view. """
view_name
=
'commerce_api:v1:orders:detail'
ORDER_NUMBER
=
'EDX-100001'
MOCK_ORDER
=
{
'number'
:
ORDER_NUMBER
}
path
=
reverse
(
view_name
,
kwargs
=
{
'number'
:
ORDER_NUMBER
})
def
setUp
(
self
):
super
(
OrderViewTests
,
self
)
.
setUp
()
self
.
_login
()
def
test_order_found
(
self
):
""" If the order is located, the view should pass the data from the API. """
with
mock_order_endpoint
(
order_number
=
self
.
ORDER_NUMBER
,
response
=
self
.
MOCK_ORDER
):
response
=
self
.
client
.
get
(
self
.
path
)
self
.
assertEqual
(
response
.
status_code
,
200
)
actual
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
actual
,
self
.
MOCK_ORDER
)
def
test_order_not_found
(
self
):
""" If the order is not found, the view should return a 404. """
with
mock_order_endpoint
(
order_number
=
self
.
ORDER_NUMBER
,
exception
=
exceptions
.
HttpNotFoundError
):
response
=
self
.
client
.
get
(
self
.
path
)
self
.
assertEqual
(
response
.
status_code
,
404
)
def
test_login_required
(
self
):
""" The view should return 403 if the user is not logged in. """
self
.
client
.
logout
()
response
=
self
.
client
.
get
(
self
.
path
)
self
.
assertEqual
(
response
.
status_code
,
403
)
lms/djangoapps/commerce/api/v1/urls.py
View file @
0fece869
...
@@ -4,15 +4,19 @@ from django.conf.urls import patterns, url, include
...
@@ -4,15 +4,19 @@ from django.conf.urls import patterns, url, include
from
commerce.api.v1
import
views
from
commerce.api.v1
import
views
COURSE_URLS
=
patterns
(
COURSE_URLS
=
patterns
(
''
,
''
,
url
(
r'^$'
,
views
.
CourseListView
.
as_view
(),
name
=
'list'
),
url
(
r'^$'
,
views
.
CourseListView
.
as_view
(),
name
=
'list'
),
url
(
r'^{}/$'
.
format
(
settings
.
COURSE_ID_PATTERN
),
views
.
CourseRetrieveUpdateView
.
as_view
(),
name
=
'retrieve_update'
),
url
(
r'^{}/$'
.
format
(
settings
.
COURSE_ID_PATTERN
),
views
.
CourseRetrieveUpdateView
.
as_view
(),
name
=
'retrieve_update'
),
)
)
ORDER_URLS
=
patterns
(
''
,
url
(
r'^(?P<number>[-\w]+)/$'
,
views
.
OrderView
.
as_view
(),
name
=
'detail'
),
)
urlpatterns
=
patterns
(
urlpatterns
=
patterns
(
''
,
''
,
url
(
r'^courses/'
,
include
(
COURSE_URLS
,
namespace
=
'courses'
)),
url
(
r'^courses/'
,
include
(
COURSE_URLS
,
namespace
=
'courses'
)),
url
(
r'^orders/'
,
include
(
ORDER_URLS
,
namespace
=
'orders'
)),
)
)
lms/djangoapps/commerce/api/v1/views.py
View file @
0fece869
...
@@ -2,16 +2,20 @@
...
@@ -2,16 +2,20 @@
import
logging
import
logging
from
django.http
import
Http404
from
django.http
import
Http404
from
edx_rest_api_client
import
exceptions
from
rest_framework.authentication
import
SessionAuthentication
from
rest_framework.authentication
import
SessionAuthentication
from
rest_framework
_oauth.authentication
import
OAuth2Authentication
from
rest_framework
.views
import
APIView
from
rest_framework.generics
import
RetrieveUpdateAPIView
,
ListAPIView
from
rest_framework.generics
import
RetrieveUpdateAPIView
,
ListAPIView
from
rest_framework.permissions
import
IsAuthenticated
from
rest_framework.permissions
import
IsAuthenticated
from
rest_framework_oauth.authentication
import
OAuth2Authentication
from
commerce
import
ecommerce_api_client
from
commerce.api.v1.models
import
Course
from
commerce.api.v1.models
import
Course
from
commerce.api.v1.permissions
import
ApiKeyOrModelPermission
from
commerce.api.v1.permissions
import
ApiKeyOrModelPermission
from
commerce.api.v1.serializers
import
CourseSerializer
from
commerce.api.v1.serializers
import
CourseSerializer
from
course_modes.models
import
CourseMode
from
course_modes.models
import
CourseMode
from
openedx.core.lib.api.mixins
import
PutAsCreateMixin
from
openedx.core.lib.api.mixins
import
PutAsCreateMixin
from
util.json_request
import
JsonResponse
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
...
@@ -54,3 +58,18 @@ class CourseRetrieveUpdateView(PutAsCreateMixin, RetrieveUpdateAPIView):
...
@@ -54,3 +58,18 @@ class CourseRetrieveUpdateView(PutAsCreateMixin, RetrieveUpdateAPIView):
# There is nothing to pre-save. The default behavior changes the Course.id attribute from
# There is nothing to pre-save. The default behavior changes the Course.id attribute from
# a CourseKey to a string, which is not desired.
# a CourseKey to a string, which is not desired.
pass
pass
class
OrderView
(
APIView
):
""" Retrieve order details. """
authentication_classes
=
(
SessionAuthentication
,)
permission_classes
=
(
IsAuthenticated
,)
def
get
(
self
,
request
,
number
):
# pylint:disable=unused-argument
""" HTTP handler. """
try
:
order
=
ecommerce_api_client
(
request
.
user
)
.
orders
(
number
)
.
get
()
return
JsonResponse
(
order
)
except
exceptions
.
HttpNotFoundError
:
return
JsonResponse
(
status
=
404
)
lms/djangoapps/commerce/tests/mocks.py
View file @
0fece869
...
@@ -103,3 +103,17 @@ class mock_create_refund(mock_ecommerce_api_endpoint): # pylint: disable=invali
...
@@ -103,3 +103,17 @@ class mock_create_refund(mock_ecommerce_api_endpoint): # pylint: disable=invali
def
get_uri
(
self
):
def
get_uri
(
self
):
return
TEST_API_URL
+
'/refunds/'
return
TEST_API_URL
+
'/refunds/'
class
mock_order_endpoint
(
mock_ecommerce_api_endpoint
):
# pylint: disable=invalid-name
""" Mocks calls to E-Commerce API client basket order method. """
default_response
=
{
'number'
:
'EDX-100001'
}
method
=
httpretty
.
GET
def
__init__
(
self
,
order_number
,
**
kwargs
):
super
(
mock_order_endpoint
,
self
)
.
__init__
(
**
kwargs
)
self
.
order_number
=
order_number
def
get_uri
(
self
):
return
TEST_API_URL
+
'/orders/{}/'
.
format
(
self
.
order_number
)
lms/static/js/commerce/views/receipt_view.js
View file @
0fece869
...
@@ -10,9 +10,13 @@ var edx = edx || {};
...
@@ -10,9 +10,13 @@ var edx = edx || {};
edx
.
commerce
.
ReceiptView
=
Backbone
.
View
.
extend
({
edx
.
commerce
.
ReceiptView
=
Backbone
.
View
.
extend
({
useEcommerceApi
:
true
,
useEcommerceApi
:
true
,
ecommerceBasketId
:
null
,
ecommerceOrderNumber
:
null
,
initialize
:
function
()
{
initialize
:
function
()
{
this
.
useEcommerceApi
=
!!
(
$
.
url
(
'?basket_id'
));
this
.
ecommerceBasketId
=
$
.
url
(
'?basket_id'
);
this
.
ecommerceOrderNumber
=
$
.
url
(
'?orderNum'
);
this
.
useEcommerceApi
=
this
.
ecommerceBasketId
||
this
.
ecommerceOrderNumber
;
_
.
bindAll
(
this
,
'renderReceipt'
,
'renderError'
,
'getProviderData'
,
'renderProvider'
,
'getCourseData'
);
_
.
bindAll
(
this
,
'renderReceipt'
,
'renderError'
,
'getProviderData'
,
'renderProvider'
,
'getCourseData'
);
/* Mix non-conflicting functions from underscore.string (all but include, contains, and reverse) into
/* Mix non-conflicting functions from underscore.string (all but include, contains, and reverse) into
...
@@ -75,7 +79,7 @@ var edx = edx || {};
...
@@ -75,7 +79,7 @@ var edx = edx || {};
render
:
function
()
{
render
:
function
()
{
var
self
=
this
,
var
self
=
this
,
orderId
=
$
.
url
(
'?basket_id'
)
||
$
.
url
(
'?payment-order-num'
);
orderId
=
this
.
ecommerceOrderNumber
||
this
.
ecommerceBasketId
||
$
.
url
(
'?payment-order-num'
);
if
(
orderId
&&
this
.
$el
.
data
(
'is-payment-complete'
)
===
'True'
)
{
if
(
orderId
&&
this
.
$el
.
data
(
'is-payment-complete'
)
===
'True'
)
{
// Get the order details
// Get the order details
...
@@ -106,14 +110,21 @@ var edx = edx || {};
...
@@ -106,14 +110,21 @@ var edx = edx || {};
/**
/**
* Retrieve receipt data from Oscar (via LMS).
* Retrieve receipt data from Oscar (via LMS).
* @param {
int} basketId The basket
that was purchased.
* @param {
string} orderId Identifier of the order
that was purchased.
* @return {object} JQuery Promise.
* @return {object} JQuery Promise.
*/
*/
getReceiptData
:
function
(
basketId
)
{
getReceiptData
:
function
(
orderId
)
{
var
urlFormat
=
this
.
useEcommerceApi
?
'/api/commerce/v0/baskets/%s/order/'
:
'/shoppingcart/receipt/%s/'
;
var
urlFormat
=
'/shoppingcart/receipt/%s/'
;
if
(
this
.
ecommerceOrderNumber
)
{
urlFormat
=
'/api/commerce/v1/orders/%s/'
;
}
else
if
(
this
.
ecommerceBasketId
){
urlFormat
=
'/api/commerce/v0/baskets/%s/order/'
;
}
return
$
.
ajax
({
return
$
.
ajax
({
url
:
_
.
sprintf
(
urlFormat
,
basket
Id
),
url
:
_
.
sprintf
(
urlFormat
,
order
Id
),
type
:
'GET'
,
type
:
'GET'
,
dataType
:
'json'
dataType
:
'json'
}).
retry
({
times
:
5
,
timeout
:
2000
,
statusCodes
:
[
404
]});
}).
retry
({
times
:
5
,
timeout
:
2000
,
statusCodes
:
[
404
]});
...
...
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