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
ee21bc1e
Commit
ee21bc1e
authored
Feb 16, 2017
by
Vedran Karacic
Committed by
Vedran Karačić
Feb 27, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add address and products to SDN failure model.
parent
48700115
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
92 additions
and
30 deletions
+92
-30
ecommerce/extensions/api/v2/tests/views/test_sdn.py
+1
-0
ecommerce/extensions/api/v2/views/sdn.py
+9
-3
ecommerce/extensions/basket/models.py
+1
-1
ecommerce/extensions/payment/migrations/0016_auto_20170227_1402.py
+26
-0
ecommerce/extensions/payment/models.py
+2
-0
ecommerce/extensions/payment/tests/test_utils.py
+26
-16
ecommerce/extensions/payment/utils.py
+16
-9
ecommerce/static/js/pages/basket_page.js
+3
-0
ecommerce/static/js/test/specs/pages/basket_page_spec.js
+8
-1
No files found.
ecommerce/extensions/api/v2/tests/views/test_sdn.py
View file @
ee21bc1e
...
@@ -29,6 +29,7 @@ class SDNCheckViewSetTests(TestCase):
...
@@ -29,6 +29,7 @@ class SDNCheckViewSetTests(TestCase):
self
.
PATH
,
self
.
PATH
,
data
=
json
.
dumps
({
data
=
json
.
dumps
({
'name'
:
'Tester'
,
'name'
:
'Tester'
,
'address'
:
'Testlandia'
,
'country'
:
'TE'
'country'
:
'TE'
}),
}),
content_type
=
JSON_CONTENT_TYPE
content_type
=
JSON_CONTENT_TYPE
...
...
ecommerce/extensions/api/v2/views/sdn.py
View file @
ee21bc1e
"""API endpoint for performing an SDN check on users."""
"""API endpoint for performing an SDN check on users."""
from
oscar.core.loading
import
get_model
from
requests.exceptions
import
HTTPError
,
Timeout
from
requests.exceptions
import
HTTPError
,
Timeout
from
rest_framework.views
import
APIView
from
rest_framework.views
import
APIView
from
rest_framework.permissions
import
IsAuthenticated
from
rest_framework.permissions
import
IsAuthenticated
...
@@ -6,6 +7,8 @@ from rest_framework.response import Response
...
@@ -6,6 +7,8 @@ from rest_framework.response import Response
from
ecommerce.extensions.payment.utils
import
SDNClient
from
ecommerce.extensions.payment.utils
import
SDNClient
Basket
=
get_model
(
'basket'
,
'Basket'
)
class
SDNCheckViewSet
(
APIView
):
class
SDNCheckViewSet
(
APIView
):
"""Performs an SDN check for a given user."""
"""Performs an SDN check for a given user."""
...
@@ -18,10 +21,13 @@ class SDNCheckViewSet(APIView):
...
@@ -18,10 +21,13 @@ class SDNCheckViewSet(APIView):
or failed.
or failed.
"""
"""
name
=
request
.
data
[
'name'
]
name
=
request
.
data
[
'name'
]
address
=
request
.
data
[
'address'
]
country
=
request
.
data
[
'country'
]
country
=
request
.
data
[
'country'
]
hits
=
0
hits
=
0
site_configuration
=
request
.
site
.
siteconfiguration
site_configuration
=
request
.
site
.
siteconfiguration
basket
=
Basket
.
get_basket
(
request
.
user
,
site_configuration
.
site
)
if
site_configuration
.
enable_sdn_check
:
if
site_configuration
.
enable_sdn_check
:
sdn_check
=
SDNClient
(
sdn_check
=
SDNClient
(
api_url
=
site_configuration
.
sdn_api_url
,
api_url
=
site_configuration
.
sdn_api_url
,
...
@@ -29,13 +35,13 @@ class SDNCheckViewSet(APIView):
...
@@ -29,13 +35,13 @@ class SDNCheckViewSet(APIView):
sdn_list
=
site_configuration
.
sdn_api_list
sdn_list
=
site_configuration
.
sdn_api_list
)
)
try
:
try
:
response
=
sdn_check
.
search
(
name
,
country
)
response
=
sdn_check
.
search
(
name
,
address
,
country
)
hits
=
response
[
'total'
]
hits
=
response
[
'total'
]
if
hits
>
0
:
if
hits
>
0
:
sdn_check
.
deactivate_user
(
sdn_check
.
deactivate_user
(
request
.
user
,
basket
,
request
.
site
.
siteconfiguration
,
name
,
name
,
address
,
country
,
country
,
response
response
)
)
...
...
ecommerce/extensions/basket/models.py
View file @
ee21bc1e
...
@@ -30,7 +30,7 @@ class Basket(AbstractBasket):
...
@@ -30,7 +30,7 @@ class Basket(AbstractBasket):
If no such basket exists, create a new one. If multiple such baskets exist,
If no such basket exists, create a new one. If multiple such baskets exist,
merge them into one.
merge them into one.
"""
"""
editable_baskets
=
cls
.
objects
.
filter
(
site
=
site
,
owner
=
user
,
status__in
=
Basket
.
editable_statuses
)
editable_baskets
=
cls
.
objects
.
filter
(
site
=
site
,
owner
=
user
,
status__in
=
cls
.
editable_statuses
)
if
len
(
editable_baskets
)
==
0
:
if
len
(
editable_baskets
)
==
0
:
basket
=
cls
.
create_basket
(
site
,
user
)
basket
=
cls
.
create_basket
(
site
,
user
)
else
:
else
:
...
...
ecommerce/extensions/payment/migrations/0016_auto_20170227_1402.py
0 → 100644
View file @
ee21bc1e
# -*- coding: utf-8 -*-
# Generated by Django 1.9.12 on 2017-02-27 14:02
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'catalogue'
,
'0023_auto_20170215_2234'
),
(
'payment'
,
'0015_auto_20170215_2229'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'sdncheckfailure'
,
name
=
'address'
,
field
=
models
.
CharField
(
default
=
''
,
max_length
=
60
),
),
migrations
.
AddField
(
model_name
=
'sdncheckfailure'
,
name
=
'products'
,
field
=
models
.
ManyToManyField
(
related_name
=
'sdn_failures'
,
to
=
'catalogue.Product'
),
),
]
ecommerce/extensions/payment/models.py
View file @
ee21bc1e
...
@@ -53,8 +53,10 @@ class SDNCheckFailure(TimeStampedModel):
...
@@ -53,8 +53,10 @@ class SDNCheckFailure(TimeStampedModel):
""" Record of SDN check failure. """
""" Record of SDN check failure. """
full_name
=
models
.
CharField
(
max_length
=
255
)
full_name
=
models
.
CharField
(
max_length
=
255
)
username
=
models
.
CharField
(
max_length
=
255
)
username
=
models
.
CharField
(
max_length
=
255
)
address
=
models
.
CharField
(
max_length
=
60
,
default
=
''
)
country
=
models
.
CharField
(
max_length
=
2
)
country
=
models
.
CharField
(
max_length
=
2
)
site
=
models
.
ForeignKey
(
'sites.Site'
,
verbose_name
=
_
(
'Site'
),
null
=
True
,
blank
=
True
,
on_delete
=
models
.
SET_NULL
)
site
=
models
.
ForeignKey
(
'sites.Site'
,
verbose_name
=
_
(
'Site'
),
null
=
True
,
blank
=
True
,
on_delete
=
models
.
SET_NULL
)
products
=
models
.
ManyToManyField
(
'catalogue.Product'
,
related_name
=
'sdn_failures'
)
sdn_check_response
=
JSONField
()
sdn_check_response
=
JSONField
()
def
__unicode__
(
self
):
def
__unicode__
(
self
):
...
...
ecommerce/extensions/payment/tests/test_utils.py
View file @
ee21bc1e
...
@@ -6,6 +6,7 @@ import mock
...
@@ -6,6 +6,7 @@ import mock
import
httpretty
import
httpretty
from
django.conf
import
settings
from
django.conf
import
settings
from
django.test
import
override_settings
from
django.test
import
override_settings
from
oscar.test
import
factories
from
requests.exceptions
import
HTTPError
,
Timeout
from
requests.exceptions
import
HTTPError
,
Timeout
from
ecommerce.core.models
import
User
from
ecommerce.core.models
import
User
...
@@ -42,6 +43,7 @@ class SDNCheckTests(TestCase):
...
@@ -42,6 +43,7 @@ class SDNCheckTests(TestCase):
def
setUp
(
self
):
def
setUp
(
self
):
super
(
SDNCheckTests
,
self
)
.
setUp
()
super
(
SDNCheckTests
,
self
)
.
setUp
()
self
.
name
=
'Dr. Evil'
self
.
name
=
'Dr. Evil'
self
.
address
=
'Top-secret lair'
self
.
country
=
'EL'
self
.
country
=
'EL'
self
.
user
=
self
.
create_user
(
full_name
=
self
.
name
)
self
.
user
=
self
.
create_user
(
full_name
=
self
.
name
)
self
.
site_configuration
=
self
.
site
.
siteconfiguration
self
.
site_configuration
=
self
.
site
.
siteconfiguration
...
@@ -64,6 +66,7 @@ class SDNCheckTests(TestCase):
...
@@ -64,6 +66,7 @@ class SDNCheckTests(TestCase):
'api_key'
:
self
.
site_configuration
.
sdn_api_key
,
'api_key'
:
self
.
site_configuration
.
sdn_api_key
,
'type'
:
'individual'
,
'type'
:
'individual'
,
'name'
:
self
.
name
,
'name'
:
self
.
name
,
'address'
:
self
.
address
,
'countries'
:
self
.
country
'countries'
:
self
.
country
})
})
sdn_check_url
=
'{api_url}?{params}'
.
format
(
sdn_check_url
=
'{api_url}?{params}'
.
format
(
...
@@ -79,15 +82,6 @@ class SDNCheckTests(TestCase):
...
@@ -79,15 +82,6 @@ class SDNCheckTests(TestCase):
content_type
=
'application/json'
content_type
=
'application/json'
)
)
def
assert_sdn_check_failure_recorded
(
self
,
response
):
""" Assert an SDN check failure is logged and has the correct values. """
self
.
assertEqual
(
SDNCheckFailure
.
objects
.
count
(),
1
)
sdn_object
=
SDNCheckFailure
.
objects
.
first
()
self
.
assertEqual
(
sdn_object
.
full_name
,
self
.
name
)
self
.
assertEqual
(
sdn_object
.
country
,
self
.
country
)
self
.
assertEqual
(
sdn_object
.
site
,
self
.
site_configuration
.
site
)
self
.
assertEqual
(
sdn_object
.
sdn_check_response
,
response
)
@httpretty.activate
@httpretty.activate
@override_settings
(
SDN_CHECK_REQUEST_TIMEOUT
=
0.1
)
@override_settings
(
SDN_CHECK_REQUEST_TIMEOUT
=
0.1
)
def
test_sdn_check_timeout
(
self
):
def
test_sdn_check_timeout
(
self
):
...
@@ -99,7 +93,7 @@ class SDNCheckTests(TestCase):
...
@@ -99,7 +93,7 @@ class SDNCheckTests(TestCase):
self
.
mock_sdn_response
(
mock_timeout
,
status_code
=
200
)
self
.
mock_sdn_response
(
mock_timeout
,
status_code
=
200
)
with
self
.
assertRaises
(
Timeout
):
with
self
.
assertRaises
(
Timeout
):
with
mock
.
patch
(
'ecommerce.extensions.payment.utils.logger.exception'
)
as
mock_logger
:
with
mock
.
patch
(
'ecommerce.extensions.payment.utils.logger.exception'
)
as
mock_logger
:
self
.
sdn_validator
.
search
(
self
.
name
,
self
.
country
)
self
.
sdn_validator
.
search
(
self
.
name
,
self
.
address
,
self
.
country
)
self
.
assertTrue
(
mock_logger
.
called
)
self
.
assertTrue
(
mock_logger
.
called
)
@httpretty.activate
@httpretty.activate
...
@@ -108,7 +102,7 @@ class SDNCheckTests(TestCase):
...
@@ -108,7 +102,7 @@ class SDNCheckTests(TestCase):
self
.
mock_sdn_response
(
json
.
dumps
({
'total'
:
1
}),
status_code
=
400
)
self
.
mock_sdn_response
(
json
.
dumps
({
'total'
:
1
}),
status_code
=
400
)
with
self
.
assertRaises
(
HTTPError
):
with
self
.
assertRaises
(
HTTPError
):
with
mock
.
patch
(
'ecommerce.extensions.payment.utils.logger.exception'
)
as
mock_logger
:
with
mock
.
patch
(
'ecommerce.extensions.payment.utils.logger.exception'
)
as
mock_logger
:
self
.
sdn_validator
.
search
(
self
.
name
,
self
.
country
)
self
.
sdn_validator
.
search
(
self
.
name
,
self
.
address
,
self
.
country
)
self
.
assertTrue
(
mock_logger
.
called
)
self
.
assertTrue
(
mock_logger
.
called
)
@httpretty.activate
@httpretty.activate
...
@@ -116,19 +110,35 @@ class SDNCheckTests(TestCase):
...
@@ -116,19 +110,35 @@ class SDNCheckTests(TestCase):
""" Verify the SDN check returns the number of matches and records the match. """
""" Verify the SDN check returns the number of matches and records the match. """
sdn_response
=
{
'total'
:
1
}
sdn_response
=
{
'total'
:
1
}
self
.
mock_sdn_response
(
json
.
dumps
(
sdn_response
))
self
.
mock_sdn_response
(
json
.
dumps
(
sdn_response
))
response
=
self
.
sdn_validator
.
search
(
self
.
name
,
self
.
country
)
response
=
self
.
sdn_validator
.
search
(
self
.
name
,
self
.
address
,
self
.
country
)
self
.
assertEqual
(
response
,
sdn_response
)
self
.
assertEqual
(
response
,
sdn_response
)
def
test_deactivate_user
(
self
):
def
test_deactivate_user
(
self
):
""" Verify an SDN failure is logged. """
""" Verify an SDN failure is logged. """
response
=
{
'description'
:
'Bad dude.'
}
response
=
{
'description'
:
'Bad dude.'
}
product1
=
factories
.
ProductFactory
(
stockrecords__partner__short_code
=
'first'
)
product2
=
factories
.
ProductFactory
(
stockrecords__partner__short_code
=
'second'
)
basket
=
factories
.
BasketFactory
(
owner
=
self
.
user
,
site
=
self
.
site_configuration
.
site
)
basket
.
add
(
product1
)
basket
.
add
(
product2
)
self
.
assertEqual
(
SDNCheckFailure
.
objects
.
count
(),
0
)
self
.
assertEqual
(
SDNCheckFailure
.
objects
.
count
(),
0
)
with
mock
.
patch
.
object
(
User
,
'deactivate_account'
)
as
deactivate_account
:
with
mock
.
patch
.
object
(
User
,
'deactivate_account'
)
as
deactivate_account
:
deactivate_account
.
return_value
=
True
deactivate_account
.
return_value
=
True
self
.
sdn_validator
.
deactivate_user
(
self
.
sdn_validator
.
deactivate_user
(
self
.
user
,
basket
,
self
.
site_configuration
,
self
.
name
,
self
.
name
,
self
.
address
,
self
.
country
,
self
.
country
,
response
)
response
self
.
assert_sdn_check_failure_recorded
(
response
)
)
self
.
assertEqual
(
SDNCheckFailure
.
objects
.
count
(),
1
)
sdn_object
=
SDNCheckFailure
.
objects
.
first
()
self
.
assertEqual
(
sdn_object
.
full_name
,
self
.
name
)
self
.
assertEqual
(
sdn_object
.
address
,
self
.
address
)
self
.
assertEqual
(
sdn_object
.
country
,
self
.
country
)
self
.
assertEqual
(
sdn_object
.
site
,
self
.
site_configuration
.
site
)
self
.
assertEqual
(
sdn_object
.
sdn_check_response
,
response
)
self
.
assertEqual
(
sdn_object
.
products
.
count
(),
basket
.
lines
.
count
())
self
.
assertIn
(
product1
,
sdn_object
.
products
.
all
())
self
.
assertIn
(
product2
,
sdn_object
.
products
.
all
())
ecommerce/extensions/payment/utils.py
View file @
ee21bc1e
...
@@ -73,7 +73,7 @@ class SDNClient(object):
...
@@ -73,7 +73,7 @@ class SDNClient(object):
self
.
api_key
=
api_key
self
.
api_key
=
api_key
self
.
sdn_list
=
sdn_list
self
.
sdn_list
=
sdn_list
def
search
(
self
,
name
,
country
):
def
search
(
self
,
name
,
address
,
country
):
"""
"""
Searches the OFAC list for an individual with the specified details.
Searches the OFAC list for an individual with the specified details.
The check returns zero hits if:
The check returns zero hits if:
...
@@ -83,6 +83,7 @@ class SDNClient(object):
...
@@ -83,6 +83,7 @@ class SDNClient(object):
Args:
Args:
name (str): Individual's full name.
name (str): Individual's full name.
address (str): Individual's address.
country (str): ISO 3166-1 alpha-2 country code where the individual is from.
country (str): ISO 3166-1 alpha-2 country code where the individual is from.
Returns:
Returns:
dict: SDN API response.
dict: SDN API response.
...
@@ -93,6 +94,7 @@ class SDNClient(object):
...
@@ -93,6 +94,7 @@ class SDNClient(object):
'api_key'
:
self
.
api_key
,
'api_key'
:
self
.
api_key
,
'type'
:
'individual'
,
'type'
:
'individual'
,
'name'
:
name
,
'name'
:
name
,
'address'
:
address
,
'countries'
:
country
'countries'
:
country
})
})
sdn_check_url
=
'{api_url}?{params}'
.
format
(
sdn_check_url
=
'{api_url}?{params}'
.
format
(
...
@@ -115,23 +117,28 @@ class SDNClient(object):
...
@@ -115,23 +117,28 @@ class SDNClient(object):
return
json
.
loads
(
response
.
content
)
return
json
.
loads
(
response
.
content
)
def
deactivate_user
(
self
,
user
,
site_configuration
,
name
,
country
,
search_results
):
def
deactivate_user
(
self
,
basket
,
name
,
address
,
country
,
search_results
):
""" Deactivates a user account.
""" Deactivates a user account.
Args:
Args:
user (User): User whose account should be deactivated.
basket (Basket): The user's basket.
site_configuration (SiteConfiguration): The current site's configuration.
name (str): The user's name.
name (str): The user's name.
address (str): The user's address.
country (str): ISO 3166-1 alpha-2 country code where the individual is from.
country (str): ISO 3166-1 alpha-2 country code where the individual is from.
search_results (dict): Results from a call to `search` that will
search_results (dict): Results from a call to `search` that will
be recorded as the reason for the deactivation.
be recorded as the reason for the deactivation.
"""
"""
SDNCheckFailure
.
objects
.
create
(
site
=
basket
.
site
snd_failure
=
SDNCheckFailure
.
objects
.
create
(
full_name
=
name
,
full_name
=
name
,
username
=
user
.
username
,
username
=
basket
.
owner
.
username
,
address
=
address
,
country
=
country
,
country
=
country
,
site
=
site
_configuration
.
site
,
site
=
site
,
sdn_check_response
=
search_results
sdn_check_response
=
search_results
)
)
logger
.
warning
(
'SDN check failed for user [
%
s] on site [
%
s]'
,
name
,
site_configuration
.
site
.
name
)
for
line
in
basket
.
lines
.
all
():
user
.
deactivate_account
(
site_configuration
)
snd_failure
.
products
.
add
(
line
.
product
)
logger
.
warning
(
'SDN check failed for user [
%
s] on site [
%
s]'
,
name
,
site
.
name
)
basket
.
owner
.
deactivate_account
(
site
.
siteconfiguration
)
ecommerce/static/js/pages/basket_page.js
View file @
ee21bc1e
...
@@ -169,6 +169,8 @@ define([
...
@@ -169,6 +169,8 @@ define([
function
sdnCheck
(
event
)
{
function
sdnCheck
(
event
)
{
var
first_name
=
$
(
'input[name=first_name]'
).
val
(),
var
first_name
=
$
(
'input[name=first_name]'
).
val
(),
last_name
=
$
(
'input[name=last_name]'
).
val
(),
last_name
=
$
(
'input[name=last_name]'
).
val
(),
address
=
$
(
'input[name=address_line1]'
).
val
(),
city
=
$
(
'input[name=city]'
).
val
(),
country
=
$
(
'select[name=country]'
).
val
();
country
=
$
(
'select[name=country]'
).
val
();
$
.
ajax
({
$
.
ajax
({
...
@@ -181,6 +183,7 @@ define([
...
@@ -181,6 +183,7 @@ define([
},
},
data
:
JSON
.
stringify
({
data
:
JSON
.
stringify
({
'name'
:
_s
.
sprintf
(
'%s %s'
,
first_name
,
last_name
),
'name'
:
_s
.
sprintf
(
'%s %s'
,
first_name
,
last_name
),
'address'
:
_s
.
sprintf
(
'%s, %s'
,
address
,
city
),
'country'
:
country
'country'
:
country
}),
}),
async
:
false
,
async
:
false
,
...
...
ecommerce/static/js/test/specs/pages/basket_page_spec.js
View file @
ee21bc1e
define
([
define
([
'jquery'
,
'jquery'
,
'underscore'
,
'underscore'
,
'underscore.string'
,
'pages/basket_page'
,
'pages/basket_page'
,
'utils/utils'
,
'utils/utils'
,
'utils/analytics_utils'
,
'utils/analytics_utils'
,
...
@@ -12,6 +13,7 @@ define([
...
@@ -12,6 +13,7 @@ define([
],
],
function
(
$
,
function
(
$
,
_
,
_
,
_s
,
BasketPage
,
BasketPage
,
Utils
,
Utils
,
AnalyticsUtils
,
AnalyticsUtils
,
...
@@ -271,6 +273,8 @@ define([
...
@@ -271,6 +273,8 @@ define([
it
(
'should perform the SDN check'
,
function
()
{
it
(
'should perform the SDN check'
,
function
()
{
var
first_name
=
'Darth'
,
var
first_name
=
'Darth'
,
last_name
=
'Vader'
,
last_name
=
'Vader'
,
address
=
'Deck 1'
,
city
=
'Death Star'
,
country
=
'DS'
,
country
=
'DS'
,
args
,
args
,
ajaxData
,
ajaxData
,
...
@@ -279,6 +283,8 @@ define([
...
@@ -279,6 +283,8 @@ define([
$
(
'input[name=first_name]'
).
val
(
first_name
);
$
(
'input[name=first_name]'
).
val
(
first_name
);
$
(
'input[name=last_name]'
).
val
(
last_name
);
$
(
'input[name=last_name]'
).
val
(
last_name
);
$
(
'input[name=address_line1]'
).
val
(
address
);
$
(
'input[name=city]'
).
val
(
city
);
$
(
'select[name=country]'
).
val
(
country
);
$
(
'select[name=country]'
).
val
(
country
);
$
(
'input[name=sdn-check]'
).
val
(
'enabled'
);
$
(
'input[name=sdn-check]'
).
val
(
'enabled'
);
...
@@ -297,7 +303,8 @@ define([
...
@@ -297,7 +303,8 @@ define([
expect
(
args
.
method
).
toEqual
(
'POST'
);
expect
(
args
.
method
).
toEqual
(
'POST'
);
expect
(
args
.
url
).
toEqual
(
'/api/v2/sdn/search/'
);
expect
(
args
.
url
).
toEqual
(
'/api/v2/sdn/search/'
);
expect
(
args
.
contentType
).
toEqual
(
'application/json; charset=utf-8'
);
expect
(
args
.
contentType
).
toEqual
(
'application/json; charset=utf-8'
);
expect
(
ajaxData
.
name
).
toEqual
(
'Darth Vader'
);
expect
(
ajaxData
.
name
).
toEqual
(
_s
.
sprintf
(
'%s %s'
,
first_name
,
last_name
));
expect
(
ajaxData
.
address
).
toEqual
(
_s
.
sprintf
(
'%s, %s'
,
address
,
city
));
expect
(
ajaxData
.
country
).
toEqual
(
country
);
expect
(
ajaxData
.
country
).
toEqual
(
country
);
});
});
});
});
...
...
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