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
05a72486
Commit
05a72486
authored
Sep 17, 2015
by
Saleem Latif
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
date format "Monday at 3pm UTC" added for courses starting with-in 5 days
parent
70866104
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
198 additions
and
3 deletions
+198
-3
common/djangoapps/util/date_utils.py
+4
-1
common/djangoapps/util/tests/test_date_utils.py
+2
-0
common/lib/xmodule/xmodule/course_metadata_utils.py
+14
-1
common/test/acceptance/fixtures/course.py
+21
-0
common/test/acceptance/pages/lms/dashboard.py
+12
-1
common/test/acceptance/tests/lms/test_lms_dashboard.py
+136
-0
lms/templates/dashboard/_dashboard_course_listing.html
+2
-0
openedx/core/djangoapps/content/course_overviews/models.py
+7
-0
No files found.
common/djangoapps/util/date_utils.py
View file @
05a72486
...
...
@@ -98,6 +98,7 @@ DEFAULT_SHORT_DATE_FORMAT = "%b %d, %Y"
DEFAULT_LONG_DATE_FORMAT
=
"
%
A,
%
B
%
d,
%
Y"
DEFAULT_TIME_FORMAT
=
"
%
I:
%
M:
%
S
%
p"
DEFAULT_DATE_TIME_FORMAT
=
"
%
b
%
d,
%
Y at
%
H:
%
M"
DEFAULT_DAY_AND_TIME_FORMAT
=
"
%
A at
%-
I
%
P"
def
strftime_localized
(
dtime
,
format
):
# pylint: disable=redefined-builtin
...
...
@@ -147,6 +148,8 @@ def strftime_localized(dtime, format): # pylint: disable=redefined-builtin
format
=
ugettext
(
"DATE_TIME_FORMAT"
)
if
format
==
"DATE_TIME_FORMAT"
:
format
=
DEFAULT_DATE_TIME_FORMAT
elif
format
==
"DAY_AND_TIME"
:
format
=
DEFAULT_DAY_AND_TIME_FORMAT
elif
format
==
"TIME"
:
format
=
"
%
X"
...
...
@@ -204,7 +207,7 @@ def strftime_localized(dtime, format): # pylint: disable=redefined-builtin
return
part
formatted_date
=
re
.
sub
(
r"
%
.|
%
"
,
process_percent_code
,
format
)
formatted_date
=
re
.
sub
(
r"
%
-
.|
%
.|
%
"
,
process_percent_code
,
format
)
return
formatted_date
...
...
common/djangoapps/util/tests/test_date_utils.py
View file @
05a72486
...
...
@@ -146,6 +146,7 @@ class StrftimeLocalizedTest(unittest.TestCase):
(
u'
%
Y년
%
m월
%
d일'
,
u"2013년 02월 14일"
),
(
"
%
a,
%
b
%
d,
%
Y"
,
"Thu, Feb 14, 2013"
),
(
"
%
I:
%
M:
%
S
%
p"
,
"04:41:17 PM"
),
(
"
%
A at
%-
I
%
P"
,
"Thursday at 4pm"
),
)
def
test_usual_strftime_behavior
(
self
,
(
fmt
,
expected
)):
dtime
=
datetime
(
2013
,
02
,
14
,
16
,
41
,
17
)
...
...
@@ -157,6 +158,7 @@ class StrftimeLocalizedTest(unittest.TestCase):
(
"SHORT_DATE"
,
"Feb 14, 2013"
),
(
"LONG_DATE"
,
"Thursday, February 14, 2013"
),
(
"TIME"
,
"04:41:17 PM"
),
(
"DAY_AND_TIME"
,
"Thursday at 4pm"
),
(
"
%
x
%
X!"
,
"Feb 14, 2013 04:41:17 PM!"
),
)
def
test_shortcuts
(
self
,
(
fmt
,
expected
)):
...
...
common/lib/xmodule/xmodule/course_metadata_utils.py
View file @
05a72486
...
...
@@ -6,6 +6,7 @@ allows us to share code between the CourseDescriptor and CourseOverview
classes, which both need these type of functions.
"""
from
datetime
import
datetime
from
datetime
import
timedelta
from
base64
import
b32encode
from
django.utils.timezone
import
UTC
...
...
@@ -105,6 +106,18 @@ def has_course_ended(end_date):
return
datetime
.
now
(
UTC
())
>
end_date
if
end_date
is
not
None
else
False
def
course_starts_within
(
start_date
,
look_ahead_days
):
"""
Given a course's start datetime and look ahead days, returns True if
course's start date falls within look ahead days otherwise False
Arguments:
start_date (datetime): The start datetime of the course in question.
look_ahead_days (int): number of days to see in future for course start date.
"""
return
datetime
.
now
(
UTC
())
+
timedelta
(
days
=
look_ahead_days
)
>
start_date
def
course_start_date_is_default
(
start
,
advertised_start
):
"""
Returns whether a course's start date hasn't yet been set.
...
...
@@ -132,7 +145,7 @@ def _datetime_to_string(date_time, format_string, strftime_localized):
# TODO: Is manually appending UTC really the right thing to do here? What if date_time isn't UTC?
result
=
strftime_localized
(
date_time
,
format_string
)
return
(
result
+
u" UTC"
if
format_string
in
[
'DATE_TIME'
,
'TIME'
]
result
+
u" UTC"
if
format_string
in
[
'DATE_TIME'
,
'TIME'
,
'DAY_AND_TIME'
]
else
result
)
...
...
common/test/acceptance/fixtures/course.py
View file @
05a72486
...
...
@@ -152,6 +152,21 @@ class CourseFixture(XBlockContainerFixture):
"""
return
"<CourseFixture: org='{org}', number='{number}', run='{run}'>"
.
format
(
**
self
.
_course_dict
)
def
add_course_details
(
self
,
course_details
):
"""
Add course details to dict of course details to be updated when configure_course or install is called.
Arguments:
Dictionary containing key value pairs for course updates,
e.g. {'start_date': datetime.now() }
"""
if
'start_date'
in
course_details
:
course_details
[
'start_date'
]
=
course_details
[
'start_date'
]
.
isoformat
()
if
'end_date'
in
course_details
:
course_details
[
'end_date'
]
=
course_details
[
'end_date'
]
.
isoformat
()
self
.
_course_details
.
update
(
course_details
)
def
add_update
(
self
,
update
):
"""
Add an update to the course. `update` should be a `CourseUpdateDesc`.
...
...
@@ -201,6 +216,12 @@ class CourseFixture(XBlockContainerFixture):
return
self
def
configure_course
(
self
):
"""
Configure Course Settings, take new course settings from self._course_details dict object
"""
self
.
_configure_course
()
@property
def
_course_location
(
self
):
"""
...
...
common/test/acceptance/pages/lms/dashboard.py
View file @
05a72486
...
...
@@ -2,7 +2,6 @@
"""
Student dashboard page.
"""
from
bok_choy.page_object
import
PageObject
from
.
import
BASE_URL
...
...
@@ -157,6 +156,18 @@ class DashboardPage(PageObject):
""" Retrieves the specified social sharing widget by its classification """
return
self
.
q
(
css
=
'a.action-{}'
.
format
(
widget_name
))
def
get_courses
(
self
):
"""
Get all courses shown in the dashboard
"""
return
self
.
q
(
css
=
'ul.listing-courses .course-item'
)
def
get_course_date
(
self
):
"""
Get course date of the first course from dashboard
"""
return
self
.
q
(
css
=
'ul.listing-courses .course-item .info-date-block'
)
.
first
.
text
[
0
]
def
click_username_dropdown
(
self
):
"""
Click username dropdown.
...
...
common/test/acceptance/tests/lms/test_lms_dashboard.py
View file @
05a72486
...
...
@@ -2,11 +2,16 @@
"""
End-to-end tests for the main LMS Dashboard (aka, Student Dashboard).
"""
import
datetime
from
..helpers
import
UniqueCourseTest
from
...fixtures.course
import
CourseFixture
from
...pages.lms.auto_auth
import
AutoAuthPage
from
...pages.lms.dashboard
import
DashboardPage
DEFAULT_SHORT_DATE_FORMAT
=
"
%
b
%
d,
%
Y"
DEFAULT_DAY_AND_TIME_FORMAT
=
"
%
A at
%-
I
%
P"
class
BaseLmsDashboardTest
(
UniqueCourseTest
):
""" Base test suite for the LMS Student Dashboard """
...
...
@@ -51,6 +56,12 @@ class BaseLmsDashboardTest(UniqueCourseTest):
class
LmsDashboardPageTest
(
BaseLmsDashboardTest
):
""" Test suite for the LMS Student Dashboard page """
def
setUp
(
self
):
super
(
LmsDashboardPageTest
,
self
)
.
setUp
()
# now datetime for usage in tests
self
.
now
=
datetime
.
datetime
.
now
()
def
test_dashboard_course_listings
(
self
):
"""
Perform a general validation of the course listings section
...
...
@@ -81,3 +92,128 @@ class LmsDashboardPageTest(BaseLmsDashboardTest):
self
.
assertEqual
(
facebook_widget
.
attrs
(
'target'
)[
0
],
'_blank'
)
self
.
assertIn
(
facebook_url
,
facebook_widget
.
attrs
(
'href'
)[
0
])
self
.
assertIn
(
facebook_url
,
facebook_widget
.
attrs
(
'onclick'
)[
0
])
def
test_ended_course_date
(
self
):
"""
Scenario:
Course Date should have the format 'Ended - Sep 23, 2015'
if the course on student dashboard has ended.
As a Student,
Given that I have enrolled to a course
And the course has ended in the past
When I visit dashboard page
Then the course date should have the following format "Ended -
%
b
%
d,
%
Y" e.g. "Ended - Sep 23, 2015"
"""
course_start_date
=
datetime
.
datetime
(
1970
,
1
,
1
)
course_end_date
=
self
.
now
-
datetime
.
timedelta
(
days
=
90
)
self
.
course_fixture
.
add_course_details
({
'start_date'
:
course_start_date
,
'end_date'
:
course_end_date
})
self
.
course_fixture
.
configure_course
()
end_date
=
course_end_date
.
strftime
(
DEFAULT_SHORT_DATE_FORMAT
)
expected_course_date
=
"Ended - {end_date}"
.
format
(
end_date
=
end_date
)
# reload the page for changes to course date changes to appear in dashboard
self
.
dashboard_page
.
visit
()
course_date
=
self
.
dashboard_page
.
get_course_date
()
# Test that proper course date with 'ended' message is displayed if a course has already ended
self
.
assertEqual
(
course_date
,
expected_course_date
)
def
test_running_course_date
(
self
):
"""
Scenario:
Course Date should have the format 'Started - Sep 23, 2015'
if the course on student dashboard is running.
As a Student,
Given that I have enrolled to a course
And the course has started
And the course is in progress
When I visit dashboard page
Then the course date should have the following format "Started -
%
b
%
d,
%
Y" e.g. "Started - Sep 23, 2015"
"""
course_start_date
=
datetime
.
datetime
(
1970
,
1
,
1
)
course_end_date
=
self
.
now
+
datetime
.
timedelta
(
days
=
90
)
self
.
course_fixture
.
add_course_details
({
'start_date'
:
course_start_date
,
'end_date'
:
course_end_date
})
self
.
course_fixture
.
configure_course
()
start_date
=
course_start_date
.
strftime
(
DEFAULT_SHORT_DATE_FORMAT
)
expected_course_date
=
"Started - {start_date}"
.
format
(
start_date
=
start_date
)
# reload the page for changes to course date changes to appear in dashboard
self
.
dashboard_page
.
visit
()
course_date
=
self
.
dashboard_page
.
get_course_date
()
# Test that proper course date with 'started' message is displayed if a course is in running state
self
.
assertEqual
(
course_date
,
expected_course_date
)
def
test_future_course_date
(
self
):
"""
Scenario:
Course Date should have the format 'Starts - Sep 23, 2015'
if the course on student dashboard starts in future.
As a Student,
Given that I have enrolled to a course
And the course starts in future
And the course does not start within 5 days
When I visit dashboard page
Then the course date should have the following format "Starts -
%
b
%
d,
%
Y" e.g. "Starts - Sep 23, 2015"
"""
course_start_date
=
self
.
now
+
datetime
.
timedelta
(
days
=
30
)
course_end_date
=
self
.
now
+
datetime
.
timedelta
(
days
=
365
)
self
.
course_fixture
.
add_course_details
({
'start_date'
:
course_start_date
,
'end_date'
:
course_end_date
})
self
.
course_fixture
.
configure_course
()
start_date
=
course_start_date
.
strftime
(
DEFAULT_SHORT_DATE_FORMAT
)
expected_course_date
=
"Starts - {start_date}"
.
format
(
start_date
=
start_date
)
# reload the page for changes to course date changes to appear in dashboard
self
.
dashboard_page
.
visit
()
course_date
=
self
.
dashboard_page
.
get_course_date
()
# Test that proper course date with 'starts' message is displayed if a course is about to start in future,
# and course does not start within 5 days
self
.
assertEqual
(
course_date
,
expected_course_date
)
def
test_near_future_course_date
(
self
):
"""
Scenario:
Course Date should have the format 'Starts - Wednesday at 5am UTC'
if the course on student dashboard starts within 5 days.
As a Student,
Given that I have enrolled to a course
And the course starts within 5 days
When I visit dashboard page
Then the course date should have the following format "Starts -
%
A at
%-
I
%
P UTC"
e.g. "Starts - Wednesday at 5am UTC"
"""
course_start_date
=
self
.
now
+
datetime
.
timedelta
(
days
=
2
)
course_end_date
=
self
.
now
+
datetime
.
timedelta
(
days
=
365
)
self
.
course_fixture
.
add_course_details
({
'start_date'
:
course_start_date
,
'end_date'
:
course_end_date
})
self
.
course_fixture
.
configure_course
()
start_date
=
course_start_date
.
strftime
(
DEFAULT_DAY_AND_TIME_FORMAT
)
expected_course_date
=
"Starts - {start_date} UTC"
.
format
(
start_date
=
start_date
)
# reload the page for changes to course date changes to appear in dashboard
self
.
dashboard_page
.
visit
()
course_date
=
self
.
dashboard_page
.
get_course_date
()
# Test that proper course date with 'starts' message is displayed if a course is about to start in future,
# and course starts within 5 days
self
.
assertEqual
(
course_date
,
expected_course_date
)
lms/templates/dashboard/_dashboard_course_listing.html
View file @
05a72486
...
...
@@ -94,6 +94,8 @@ from student.helpers import (
${_("Started - {start_date}").format(start_date=course_overview.start_datetime_text("SHORT_DATE"))}
% elif course_overview.start_date_is_still_default: # Course start date TBD
${_("Coming Soon")}
% elif course_overview.starts_within(days=5): # hasn't started yet
${_("Starts - {start_date}").format(start_date=course_overview.start_datetime_text("DAY_AND_TIME"))}
% else: # hasn't started yet
${_("Starts - {start_date}").format(start_date=course_overview.start_datetime_text("SHORT_DATE"))}
% endif
...
...
openedx/core/djangoapps/content/course_overviews/models.py
View file @
05a72486
...
...
@@ -289,6 +289,13 @@ class CourseOverview(TimeStampedModel):
"""
return
course_metadata_utils
.
has_course_ended
(
self
.
end
)
def
starts_within
(
self
,
days
):
"""
Returns True if the course starts with-in given number of days otherwise returns False.
"""
return
course_metadata_utils
.
course_starts_within
(
self
.
start
,
days
)
def
start_datetime_text
(
self
,
format_string
=
"SHORT_DATE"
):
"""
Returns the desired text corresponding the course's start date and
...
...
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