Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-analytics-data-api
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-analytics-data-api
Commits
5e6dedcd
Commit
5e6dedcd
authored
Aug 29, 2014
by
Clinton Blackburn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Test Cleanup
Extracted mixins to make tests a bit more extensible. Removed some duplicated code.
parent
0674b790
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
157 additions
and
135 deletions
+157
-135
Makefile
+1
-1
analytics_data_api/v0/tests/test_views.py
+155
-134
requirements/test.txt
+1
-0
No files found.
Makefile
View file @
5e6dedcd
...
@@ -20,7 +20,7 @@ clean:
...
@@ -20,7 +20,7 @@ clean:
coverage erase
coverage erase
test
:
clean
test
:
clean
.
./.test_env
&&
./manage.py
test
--settings
=
analyticsdataserver.settings.test
\
.
./.test_env
&&
./manage.py
test
--settings
=
analyticsdataserver.settings.test
--with-ignore-docstrings
\
--exclude-dir
=
analyticsdataserver/settings
--with-coverage
--cover-inclusive
--cover-branches
\
--exclude-dir
=
analyticsdataserver/settings
--with-coverage
--cover-inclusive
--cover-branches
\
--cover-html
--cover-html-dir
=
$(COVERAGE)
/html/
\
--cover-html
--cover-html-dir
=
$(COVERAGE)
/html/
\
--cover-xml
--cover-xml-file
=
$(COVERAGE)
/coverage.xml
\
--cover-xml
--cover-xml-file
=
$(COVERAGE)
/coverage.xml
\
...
...
analytics_data_api/v0/tests/test_views.py
View file @
5e6dedcd
...
@@ -16,6 +16,112 @@ from analytics_data_api.v0.tests.utils import flatten
...
@@ -16,6 +16,112 @@ from analytics_data_api.v0.tests.utils import flatten
from
analyticsdataserver.tests
import
TestCaseWithAuthentication
from
analyticsdataserver.tests
import
TestCaseWithAuthentication
# pylint: disable=no-member
class
CourseViewTestCaseMixin
(
object
):
model
=
None
api_root_path
=
'/api/v0/'
path
=
None
order_by
=
[]
def
format_as_response
(
self
,
*
args
):
"""
Format given data as a response that would be issued by the endpoint.
Arguments
args -- Iterable list of objects
"""
raise
NotImplementedError
def
get_latest_data
(
self
):
"""
Return the latest row/rows that would be returned if a user made a call
to the endpoint with no date filtering.
Return value must be an iterable.
"""
raise
NotImplementedError
def
test_get_not_found
(
self
):
""" Requests made against non-existent courses should return a 404 """
course_id
=
'edX/DemoX/Non_Existent_Course'
response
=
self
.
authenticated_get
(
'
%
scourses/
%
s
%
s'
%
(
self
.
api_root_path
,
course_id
,
self
.
path
))
self
.
assertEquals
(
response
.
status_code
,
404
)
def
test_get
(
self
):
""" Verify the endpoint returns an HTTP 200 status and the correct data. """
# Validate the basic response status
response
=
self
.
authenticated_get
(
'
%
scourses/
%
s
%
s'
%
(
self
.
api_root_path
,
self
.
course_id
,
self
.
path
))
self
.
assertEquals
(
response
.
status_code
,
200
)
# Validate the data is correct and sorted chronologically
expected
=
self
.
format_as_response
(
*
self
.
get_latest_data
())
self
.
assertEquals
(
response
.
data
,
expected
)
def
test_get_csv
(
self
):
""" Verify the endpoint returns data that has been properly converted to CSV. """
path
=
'
%
scourses/
%
s
%
s'
%
(
self
.
api_root_path
,
self
.
course_id
,
self
.
path
)
csv_content_type
=
'text/csv'
response
=
self
.
authenticated_get
(
path
,
HTTP_ACCEPT
=
csv_content_type
)
# Validate the basic response status and content code
self
.
assertEquals
(
response
.
status_code
,
200
)
self
.
assertEquals
(
response
[
'Content-Type'
]
.
split
(
';'
)[
0
],
csv_content_type
)
# Validate the actual data
data
=
self
.
format_as_response
(
*
self
.
get_latest_data
())
data
=
map
(
flatten
,
data
)
# The CSV renderer sorts the headers alphabetically
fieldnames
=
sorted
(
data
[
0
]
.
keys
())
# Generate the expected CSV output
expected
=
StringIO
.
StringIO
()
writer
=
csv
.
DictWriter
(
expected
,
fieldnames
)
writer
.
writeheader
()
writer
.
writerows
(
data
)
self
.
assertEqual
(
response
.
content
,
expected
.
getvalue
())
def
test_get_with_intervals
(
self
):
""" Verify the endpoint returns multiple data points when supplied with an interval of dates. """
raise
NotImplementedError
def
assertIntervalFilteringWorks
(
self
,
expected_response
,
start_date
,
end_date
):
# If start date is after date of existing data, no data should be returned
date
=
(
start_date
+
datetime
.
timedelta
(
days
=
30
))
.
strftime
(
settings
.
DATE_FORMAT
)
response
=
self
.
authenticated_get
(
'
%
scourses/
%
s
%
s?start_date=
%
s'
%
(
self
.
api_root_path
,
self
.
course_id
,
self
.
path
,
date
))
self
.
assertEquals
(
response
.
status_code
,
200
)
self
.
assertListEqual
([],
response
.
data
)
# If end date is before date of existing data, no data should be returned
date
=
(
start_date
-
datetime
.
timedelta
(
days
=
30
))
.
strftime
(
settings
.
DATE_FORMAT
)
response
=
self
.
authenticated_get
(
'
%
scourses/
%
s
%
s?end_date=
%
s'
%
(
self
.
api_root_path
,
self
.
course_id
,
self
.
path
,
date
))
self
.
assertEquals
(
response
.
status_code
,
200
)
self
.
assertListEqual
([],
response
.
data
)
# If data falls in date range, data should be returned
start_date
=
start_date
.
strftime
(
settings
.
DATE_FORMAT
)
end_date
=
end_date
.
strftime
(
settings
.
DATE_FORMAT
)
response
=
self
.
authenticated_get
(
'
%
scourses/
%
s
%
s?start_date=
%
s&end_date=
%
s'
%
(
self
.
api_root_path
,
self
.
course_id
,
self
.
path
,
start_date
,
end_date
))
self
.
assertEquals
(
response
.
status_code
,
200
)
self
.
assertListEqual
(
response
.
data
,
expected_response
)
class
CourseEnrollmentViewTestCaseMixin
(
CourseViewTestCaseMixin
):
def
setUp
(
self
):
super
(
CourseEnrollmentViewTestCaseMixin
,
self
)
.
setUp
()
self
.
course_id
=
'edX/DemoX/Demo_Course'
self
.
date
=
datetime
.
date
(
2014
,
1
,
1
)
def
get_latest_data
(
self
):
return
self
.
model
.
objects
.
filter
(
date
=
self
.
date
)
.
order_by
(
'date'
,
*
self
.
order_by
)
def
test_get_with_intervals
(
self
):
expected
=
self
.
format_as_response
(
*
self
.
model
.
objects
.
filter
(
date
=
self
.
date
))
self
.
assertIntervalFilteringWorks
(
expected
,
self
.
date
,
self
.
date
+
datetime
.
timedelta
(
days
=
1
))
class
CourseActivityLastWeekTest
(
TestCaseWithAuthentication
):
class
CourseActivityLastWeekTest
(
TestCaseWithAuthentication
):
# pylint: disable=line-too-long
# pylint: disable=line-too-long
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -98,96 +204,19 @@ class CourseActivityLastWeekTest(TestCaseWithAuthentication):
...
@@ -98,96 +204,19 @@ class CourseActivityLastWeekTest(TestCaseWithAuthentication):
self
.
assertEquals
(
response
.
data
,
self
.
get_activity_record
(
activity_type
=
activity_type
,
count
=
400
))
self
.
assertEquals
(
response
.
data
,
self
.
get_activity_record
(
activity_type
=
activity_type
,
count
=
400
))
# pylint: disable=no-member
class
CourseEnrollmentByBirthYearViewTests
(
CourseEnrollmentViewTestCaseMixin
,
TestCaseWithAuthentication
):
class
CourseEnrollmentViewTestCase
(
object
):
model
=
None
path
=
None
order_by
=
[]
def
get_expected_response
(
self
,
*
args
):
raise
NotImplementedError
def
test_get_not_found
(
self
):
""" Requests made against non-existent courses should return a 404 """
course_id
=
'edX/DemoX/Non_Existent_Course'
response
=
self
.
authenticated_get
(
'/api/v0/courses/
%
s
%
s'
%
(
course_id
,
self
.
path
))
self
.
assertEquals
(
response
.
status_code
,
404
)
def
test_get
(
self
):
# Validate the basic response status
response
=
self
.
authenticated_get
(
'/api/v0/courses/
%
s
%
s'
%
(
self
.
course_id
,
self
.
path
,))
self
.
assertEquals
(
response
.
status_code
,
200
)
# Validate the data is correct and sorted chronologically
expected
=
self
.
get_expected_response
(
*
self
.
model
.
objects
.
filter
(
date
=
self
.
date
)
.
order_by
(
'date'
,
*
self
.
order_by
))
# pylint: disable=line-too-long
self
.
assertEquals
(
response
.
data
,
expected
)
def
test_get_csv
(
self
):
path
=
'/api/v0/courses/
%
s
%
s'
%
(
self
.
course_id
,
self
.
path
,)
csv_content_type
=
'text/csv'
response
=
self
.
authenticated_get
(
path
,
HTTP_ACCEPT
=
csv_content_type
)
# Validate the basic response status and content code
self
.
assertEquals
(
response
.
status_code
,
200
)
self
.
assertEquals
(
response
[
'Content-Type'
]
.
split
(
';'
)[
0
],
csv_content_type
)
# Validate the actual data
data
=
self
.
get_expected_response
(
*
self
.
model
.
objects
.
filter
(
date
=
self
.
date
))
data
=
map
(
flatten
,
data
)
# The CSV renderer sorts the headers alphabetically
fieldnames
=
sorted
(
data
[
0
]
.
keys
())
# Generate the expected CSV output
expected
=
StringIO
.
StringIO
()
writer
=
csv
.
DictWriter
(
expected
,
fieldnames
)
writer
.
writeheader
()
writer
.
writerows
(
data
)
self
.
assertEqual
(
response
.
content
,
expected
.
getvalue
())
def
test_get_with_intervals
(
self
):
expected
=
self
.
get_expected_response
(
*
self
.
model
.
objects
.
filter
(
date
=
self
.
date
))
self
.
assertIntervalFilteringWorks
(
expected
,
self
.
date
,
self
.
date
+
datetime
.
timedelta
(
days
=
1
))
def
assertIntervalFilteringWorks
(
self
,
expected_response
,
start_date
,
end_date
):
# If start date is after date of existing data, no data should be returned
date
=
(
start_date
+
datetime
.
timedelta
(
days
=
30
))
.
strftime
(
settings
.
DATE_FORMAT
)
response
=
self
.
authenticated_get
(
'/api/v0/courses/
%
s
%
s?start_date=
%
s'
%
(
self
.
course_id
,
self
.
path
,
date
))
self
.
assertEquals
(
response
.
status_code
,
200
)
self
.
assertListEqual
([],
response
.
data
)
# If end date is before date of existing data, no data should be returned
date
=
(
start_date
-
datetime
.
timedelta
(
days
=
30
))
.
strftime
(
settings
.
DATE_FORMAT
)
response
=
self
.
authenticated_get
(
'/api/v0/courses/
%
s
%
s?end_date=
%
s'
%
(
self
.
course_id
,
self
.
path
,
date
))
self
.
assertEquals
(
response
.
status_code
,
200
)
self
.
assertListEqual
([],
response
.
data
)
# If data falls in date range, data should be returned
start_date
=
start_date
.
strftime
(
settings
.
DATE_FORMAT
)
end_date
=
end_date
.
strftime
(
settings
.
DATE_FORMAT
)
response
=
self
.
authenticated_get
(
'/api/v0/courses/
%
s
%
s?start_date=
%
s&end_date=
%
s'
%
(
self
.
course_id
,
self
.
path
,
start_date
,
end_date
))
self
.
assertEquals
(
response
.
status_code
,
200
)
self
.
assertListEqual
(
response
.
data
,
expected_response
)
class
CourseEnrollmentByBirthYearViewTests
(
TestCaseWithAuthentication
,
CourseEnrollmentViewTestCase
):
path
=
'/enrollment/birth_year'
path
=
'/enrollment/birth_year'
model
=
models
.
CourseEnrollmentByBirthYear
model
=
models
.
CourseEnrollmentByBirthYear
order_by
=
[
'birth_year'
]
order_by
=
[
'birth_year'
]
def
setUp
(
self
):
super
(
CourseEnrollmentByBirthYearViewTests
,
self
)
.
setUp
()
G
(
self
.
model
,
course_id
=
self
.
course_id
,
date
=
self
.
date
,
birth_year
=
1956
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
date
=
self
.
date
,
birth_year
=
1986
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
date
=
self
.
date
-
datetime
.
timedelta
(
days
=
10
),
birth_year
=
1956
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
date
=
self
.
date
-
datetime
.
timedelta
(
days
=
10
),
birth_year
=
1986
)
@classmethod
def
format_as_response
(
self
,
*
args
):
def
setUpClass
(
cls
):
cls
.
course_id
=
'edX/DemoX/Demo_Course'
cls
.
date
=
datetime
.
date
(
2014
,
1
,
1
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
date
=
cls
.
date
,
birth_year
=
1956
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
date
=
cls
.
date
,
birth_year
=
1986
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
date
=
cls
.
date
-
datetime
.
timedelta
(
days
=
10
),
birth_year
=
1956
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
date
=
cls
.
date
-
datetime
.
timedelta
(
days
=
10
),
birth_year
=
1986
)
def
get_expected_response
(
self
,
*
args
):
return
[
return
[
{
'course_id'
:
str
(
ce
.
course_id
),
'count'
:
ce
.
count
,
'date'
:
ce
.
date
.
strftime
(
settings
.
DATE_FORMAT
),
{
'course_id'
:
str
(
ce
.
course_id
),
'count'
:
ce
.
count
,
'date'
:
ce
.
date
.
strftime
(
settings
.
DATE_FORMAT
),
'birth_year'
:
ce
.
birth_year
}
for
ce
in
args
]
'birth_year'
:
ce
.
birth_year
}
for
ce
in
args
]
...
@@ -196,51 +225,47 @@ class CourseEnrollmentByBirthYearViewTests(TestCaseWithAuthentication, CourseEnr
...
@@ -196,51 +225,47 @@ class CourseEnrollmentByBirthYearViewTests(TestCaseWithAuthentication, CourseEnr
response
=
self
.
authenticated_get
(
'/api/v0/courses/
%
s
%
s'
%
(
self
.
course_id
,
self
.
path
,))
response
=
self
.
authenticated_get
(
'/api/v0/courses/
%
s
%
s'
%
(
self
.
course_id
,
self
.
path
,))
self
.
assertEquals
(
response
.
status_code
,
200
)
self
.
assertEquals
(
response
.
status_code
,
200
)
expected
=
self
.
get_expected
_response
(
*
self
.
model
.
objects
.
filter
(
date
=
self
.
date
))
expected
=
self
.
format_as
_response
(
*
self
.
model
.
objects
.
filter
(
date
=
self
.
date
))
self
.
assertEquals
(
response
.
data
,
expected
)
self
.
assertEquals
(
response
.
data
,
expected
)
def
test_get_with_intervals
(
self
):
def
test_get_with_intervals
(
self
):
expected
=
self
.
get_expected
_response
(
*
self
.
model
.
objects
.
filter
(
date
=
self
.
date
))
expected
=
self
.
format_as
_response
(
*
self
.
model
.
objects
.
filter
(
date
=
self
.
date
))
self
.
assertIntervalFilteringWorks
(
expected
,
self
.
date
,
self
.
date
+
datetime
.
timedelta
(
days
=
1
))
self
.
assertIntervalFilteringWorks
(
expected
,
self
.
date
,
self
.
date
+
datetime
.
timedelta
(
days
=
1
))
class
CourseEnrollmentByEducationViewTests
(
TestCaseWithAuthentication
,
CourseEnrollmentViewTestCase
):
class
CourseEnrollmentByEducationViewTests
(
CourseEnrollmentViewTestCaseMixin
,
TestCaseWithAuthentication
):
path
=
'/enrollment/education/'
path
=
'/enrollment/education/'
model
=
models
.
CourseEnrollmentByEducation
model
=
models
.
CourseEnrollmentByEducation
order_by
=
[
'education_level'
]
order_by
=
[
'education_level'
]
@classmethod
def
setUp
(
self
):
def
setUpClass
(
cls
):
super
(
CourseEnrollmentByEducationViewTests
,
self
)
.
setUp
()
cls
.
el1
=
G
(
models
.
EducationLevel
,
name
=
'Doctorate'
,
short_name
=
'doctorate'
)
self
.
el1
=
G
(
models
.
EducationLevel
,
name
=
'Doctorate'
,
short_name
=
'doctorate'
)
cls
.
el2
=
G
(
models
.
EducationLevel
,
name
=
'Top Secret'
,
short_name
=
'top_secret'
)
self
.
el2
=
G
(
models
.
EducationLevel
,
name
=
'Top Secret'
,
short_name
=
'top_secret'
)
cls
.
course_id
=
'edX/DemoX/Demo_Course'
G
(
self
.
model
,
course_id
=
self
.
course_id
,
date
=
self
.
date
,
education_level
=
self
.
el1
)
cls
.
date
=
datetime
.
date
(
2014
,
1
,
1
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
date
=
self
.
date
,
education_level
=
self
.
el2
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
date
=
cls
.
date
,
education_level
=
cls
.
el1
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
date
=
self
.
date
-
datetime
.
timedelta
(
days
=
2
),
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
date
=
cls
.
date
,
education_level
=
cls
.
el2
)
education_level
=
self
.
el2
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
date
=
cls
.
date
-
datetime
.
timedelta
(
days
=
2
),
education_level
=
cls
.
el2
)
def
format_as_response
(
self
,
*
args
):
def
get_expected_response
(
self
,
*
args
):
return
[
return
[
{
'course_id'
:
str
(
ce
.
course_id
),
'count'
:
ce
.
count
,
'date'
:
ce
.
date
.
strftime
(
settings
.
DATE_FORMAT
),
{
'course_id'
:
str
(
ce
.
course_id
),
'count'
:
ce
.
count
,
'date'
:
ce
.
date
.
strftime
(
settings
.
DATE_FORMAT
),
'education_level'
:
{
'name'
:
ce
.
education_level
.
name
,
'short_name'
:
ce
.
education_level
.
short_name
}}
for
'education_level'
:
{
'name'
:
ce
.
education_level
.
name
,
'short_name'
:
ce
.
education_level
.
short_name
}}
for
ce
in
args
]
ce
in
args
]
class
CourseEnrollmentByGenderViewTests
(
TestCaseWithAuthentication
,
CourseEnrollmentViewTestCase
):
class
CourseEnrollmentByGenderViewTests
(
CourseEnrollmentViewTestCaseMixin
,
TestCaseWithAuthentication
):
path
=
'/enrollment/gender/'
path
=
'/enrollment/gender/'
model
=
models
.
CourseEnrollmentByGender
model
=
models
.
CourseEnrollmentByGender
order_by
=
[
'gender'
]
order_by
=
[
'gender'
]
@classmethod
def
setUp
(
self
):
def
setUpClass
(
cls
):
super
(
CourseEnrollmentByGenderViewTests
,
self
)
.
setUp
()
cls
.
course_id
=
'edX/DemoX/Demo_Course'
G
(
self
.
model
,
course_id
=
self
.
course_id
,
gender
=
'm'
,
date
=
self
.
date
,
count
=
34
)
cls
.
date
=
datetime
.
date
(
2014
,
1
,
1
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
gender
=
'f'
,
date
=
self
.
date
,
count
=
45
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
gender
=
'm'
,
date
=
cls
.
date
,
count
=
34
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
gender
=
'f'
,
date
=
self
.
date
-
datetime
.
timedelta
(
days
=
2
),
count
=
45
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
gender
=
'f'
,
date
=
cls
.
date
,
count
=
45
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
gender
=
'f'
,
date
=
cls
.
date
-
datetime
.
timedelta
(
days
=
2
),
count
=
45
)
def
get_expected
_response
(
self
,
*
args
):
def
format_as
_response
(
self
,
*
args
):
return
[
return
[
{
'course_id'
:
str
(
ce
.
course_id
),
'count'
:
ce
.
count
,
'date'
:
ce
.
date
.
strftime
(
settings
.
DATE_FORMAT
),
{
'course_id'
:
str
(
ce
.
course_id
),
'count'
:
ce
.
count
,
'date'
:
ce
.
date
.
strftime
(
settings
.
DATE_FORMAT
),
'gender'
:
ce
.
gender
}
for
ce
in
args
]
'gender'
:
ce
.
gender
}
for
ce
in
args
]
...
@@ -277,28 +302,26 @@ class AnswerDistributionTests(TestCaseWithAuthentication):
...
@@ -277,28 +302,26 @@ class AnswerDistributionTests(TestCaseWithAuthentication):
self
.
assertEquals
(
response
.
status_code
,
404
)
self
.
assertEquals
(
response
.
status_code
,
404
)
class
CourseEnrollmentViewTests
(
TestCaseWithAuthentication
,
CourseEnrollmentViewTestCase
):
class
CourseEnrollmentViewTests
(
CourseEnrollmentViewTestCaseMixin
,
TestCaseWithAuthentication
):
model
=
models
.
CourseEnrollmentDaily
model
=
models
.
CourseEnrollmentDaily
path
=
'/enrollment'
path
=
'/enrollment'
@classmethod
def
setUp
(
self
):
def
setUpClass
(
cls
):
super
(
CourseEnrollmentViewTests
,
self
)
.
setUp
()
cls
.
course_id
=
'edX/DemoX/Demo_Course'
G
(
self
.
model
,
course_id
=
self
.
course_id
,
date
=
self
.
date
,
count
=
203
)
cls
.
date
=
datetime
.
date
(
2014
,
1
,
1
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
date
=
self
.
date
-
datetime
.
timedelta
(
days
=
5
),
count
=
203
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
date
=
cls
.
date
,
count
=
203
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
date
=
cls
.
date
-
datetime
.
timedelta
(
days
=
5
),
count
=
203
)
def
get_expected
_response
(
self
,
*
args
):
def
format_as
_response
(
self
,
*
args
):
return
[
return
[
{
'course_id'
:
str
(
ce
.
course_id
),
'count'
:
ce
.
count
,
'date'
:
ce
.
date
.
strftime
(
settings
.
DATE_FORMAT
)}
{
'course_id'
:
str
(
ce
.
course_id
),
'count'
:
ce
.
count
,
'date'
:
ce
.
date
.
strftime
(
settings
.
DATE_FORMAT
)}
for
ce
in
args
]
for
ce
in
args
]
class
CourseEnrollmentByLocationViewTests
(
TestCaseWithAuthentication
,
CourseEnrollmentViewTestCase
):
class
CourseEnrollmentByLocationViewTests
(
CourseEnrollmentViewTestCaseMixin
,
TestCaseWithAuthentication
):
path
=
'/enrollment/location/'
path
=
'/enrollment/location/'
model
=
models
.
CourseEnrollmentByCountry
model
=
models
.
CourseEnrollmentByCountry
def
get_expected
_response
(
self
,
*
args
):
def
format_as
_response
(
self
,
*
args
):
args
=
[
arg
for
arg
in
args
if
arg
.
country_code
not
in
[
''
,
'A1'
,
'A2'
,
'AP'
,
'EU'
,
'O1'
,
'UNKNOWN'
]]
args
=
[
arg
for
arg
in
args
if
arg
.
country_code
not
in
[
''
,
'A1'
,
'A2'
,
'AP'
,
'EU'
,
'O1'
,
'UNKNOWN'
]]
args
=
sorted
(
args
,
key
=
lambda
item
:
(
item
.
date
,
item
.
course_id
,
item
.
country
.
alpha3
))
args
=
sorted
(
args
,
key
=
lambda
item
:
(
item
.
date
,
item
.
course_id
,
item
.
country
.
alpha3
))
return
[
return
[
...
@@ -306,17 +329,15 @@ class CourseEnrollmentByLocationViewTests(TestCaseWithAuthentication, CourseEnro
...
@@ -306,17 +329,15 @@ class CourseEnrollmentByLocationViewTests(TestCaseWithAuthentication, CourseEnro
'country'
:
{
'alpha2'
:
ce
.
country
.
alpha2
,
'alpha3'
:
ce
.
country
.
alpha3
,
'name'
:
ce
.
country
.
name
}}
for
ce
in
'country'
:
{
'alpha2'
:
ce
.
country
.
alpha2
,
'alpha3'
:
ce
.
country
.
alpha3
,
'name'
:
ce
.
country
.
name
}}
for
ce
in
args
]
args
]
@classmethod
def
setUp
(
self
):
def
setUpClass
(
cls
):
super
(
CourseEnrollmentByLocationViewTests
,
self
)
.
setUp
()
cls
.
course_id
=
'edX/DemoX/Demo_Course'
self
.
country
=
countries
.
get
(
'US'
)
cls
.
date
=
datetime
.
date
(
2014
,
1
,
1
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
country_code
=
'US'
,
count
=
455
,
date
=
self
.
date
)
cls
.
country
=
countries
.
get
(
'US'
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
country_code
=
'CA'
,
count
=
356
,
date
=
self
.
date
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
country_code
=
'US'
,
count
=
455
,
date
=
cls
.
date
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
country_code
=
'IN'
,
count
=
12
,
date
=
self
.
date
-
datetime
.
timedelta
(
days
=
29
))
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
country_code
=
'CA'
,
count
=
356
,
date
=
cls
.
date
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
country_code
=
''
,
count
=
356
,
date
=
self
.
date
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
country_code
=
'IN'
,
count
=
12
,
date
=
cls
.
date
-
datetime
.
timedelta
(
days
=
29
))
G
(
self
.
model
,
course_id
=
self
.
course_id
,
country_code
=
'A1'
,
count
=
1
,
date
=
self
.
date
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
country_code
=
''
,
count
=
356
,
date
=
cls
.
date
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
country_code
=
'A2'
,
count
=
2
,
date
=
self
.
date
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
country_code
=
'A1'
,
count
=
1
,
date
=
cls
.
date
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
country_code
=
'AP'
,
count
=
1
,
date
=
self
.
date
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
country_code
=
'A2'
,
count
=
2
,
date
=
cls
.
date
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
country_code
=
'EU'
,
count
=
4
,
date
=
self
.
date
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
country_code
=
'AP'
,
count
=
1
,
date
=
cls
.
date
)
G
(
self
.
model
,
course_id
=
self
.
course_id
,
country_code
=
'O1'
,
count
=
7
,
date
=
self
.
date
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
country_code
=
'EU'
,
count
=
4
,
date
=
cls
.
date
)
G
(
cls
.
model
,
course_id
=
cls
.
course_id
,
country_code
=
'O1'
,
count
=
7
,
date
=
cls
.
date
)
requirements/test.txt
View file @
5e6dedcd
...
@@ -11,3 +11,4 @@ pep257==0.3.2
...
@@ -11,3 +11,4 @@ pep257==0.3.2
pep8==1.5.7
pep8==1.5.7
pylint==1.2.1
pylint==1.2.1
pytz==2012h
pytz==2012h
nose-ignore-docstring==0.2
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