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
13b14e0a
Commit
13b14e0a
authored
Dec 17, 2015
by
muhammad-ammar
Committed by
muzaffaryousaf
Feb 24, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Paginate edxnotes frontend
TNL-3908
parent
840f5017
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
586 additions
and
249 deletions
+586
-249
common/test/acceptance/pages/lms/edxnotes.py
+1
-1
common/test/acceptance/tests/lms/test_lms_edxnotes.py
+5
-0
lms/djangoapps/edxnotes/helpers.py
+50
-36
lms/djangoapps/edxnotes/tests.py
+18
-10
lms/djangoapps/edxnotes/views.py
+2
-0
lms/envs/bok_choy.py
+2
-0
lms/envs/common.py
+3
-0
lms/envs/test.py
+2
-0
lms/static/js/edxnotes/collections/notes.js
+28
-22
lms/static/js/edxnotes/views/notes_page.js
+22
-17
lms/static/js/edxnotes/views/page_factory.js
+14
-3
lms/static/js/edxnotes/views/search_box.js
+13
-16
lms/static/js/edxnotes/views/tab_panel.js
+19
-2
lms/static/js/edxnotes/views/tab_view.js
+9
-2
lms/static/js/edxnotes/views/tabs/search_results.js
+4
-3
lms/static/js/spec/edxnotes/collections/notes_spec.js
+13
-2
lms/static/js/spec/edxnotes/helpers.js
+136
-54
lms/static/js/spec/edxnotes/models/note_spec.js
+17
-4
lms/static/js/spec/edxnotes/views/note_item_spec.js
+4
-4
lms/static/js/spec/edxnotes/views/notes_page_spec.js
+8
-3
lms/static/js/spec/edxnotes/views/search_box_spec.js
+23
-17
lms/static/js/spec/edxnotes/views/tabs/course_structure_spec.js
+1
-1
lms/static/js/spec/edxnotes/views/tabs/recent_activity_spec.js
+167
-40
lms/static/js/spec/edxnotes/views/tabs/search_results_spec.js
+0
-0
lms/static/js/spec/edxnotes/views/tabs/tags_spec.js
+1
-1
lms/static/sass/course/_student-notes.scss
+12
-6
lms/templates/edxnotes/edxnotes.html
+11
-4
lms/templates/edxnotes/note-item.underscore
+1
-1
No files found.
common/test/acceptance/pages/lms/edxnotes.py
View file @
13b14e0a
...
@@ -114,7 +114,7 @@ class EdxNotesPageItem(NoteChild):
...
@@ -114,7 +114,7 @@ class EdxNotesPageItem(NoteChild):
"""
"""
BODY_SELECTOR
=
".note"
BODY_SELECTOR
=
".note"
UNIT_LINK_SELECTOR
=
"a.reference-unit-link"
UNIT_LINK_SELECTOR
=
"a.reference-unit-link"
TAG_SELECTOR
=
"
a
.reference-tags"
TAG_SELECTOR
=
"
span
.reference-tags"
def
go_to_unit
(
self
,
unit_page
=
None
):
def
go_to_unit
(
self
,
unit_page
=
None
):
self
.
q
(
css
=
self
.
_bounded_selector
(
self
.
UNIT_LINK_SELECTOR
))
.
click
()
self
.
q
(
css
=
self
.
_bounded_selector
(
self
.
UNIT_LINK_SELECTOR
))
.
click
()
...
...
common/test/acceptance/tests/lms/test_lms_edxnotes.py
View file @
13b14e0a
"""
"""
Test LMS Notes
Test LMS Notes
"""
"""
from
unittest
import
skip
from
uuid
import
uuid4
from
uuid
import
uuid4
from
datetime
import
datetime
from
datetime
import
datetime
from
nose.plugins.attrib
import
attr
from
nose.plugins.attrib
import
attr
...
@@ -850,6 +851,7 @@ class EdxNotesPageTest(EventsTestMixin, EdxNotesTestMixin):
...
@@ -850,6 +851,7 @@ class EdxNotesPageTest(EventsTestMixin, EdxNotesTestMixin):
self
.
assert_viewed_event
(
'Search Results'
)
self
.
assert_viewed_event
(
'Search Results'
)
self
.
assert_search_event
(
'note'
,
4
)
self
.
assert_search_event
(
'note'
,
4
)
@skip
(
"scroll to tag functionality is removed"
)
def
test_scroll_to_tag_recent_activity
(
self
):
def
test_scroll_to_tag_recent_activity
(
self
):
"""
"""
Scenario: Can scroll to a tag group from the Recent Activity view (default view)
Scenario: Can scroll to a tag group from the Recent Activity view (default view)
...
@@ -861,6 +863,7 @@ class EdxNotesPageTest(EventsTestMixin, EdxNotesTestMixin):
...
@@ -861,6 +863,7 @@ class EdxNotesPageTest(EventsTestMixin, EdxNotesTestMixin):
self
.
notes_page
.
visit
()
self
.
notes_page
.
visit
()
self
.
_scroll_to_tag_and_verify
(
"pear"
,
3
)
self
.
_scroll_to_tag_and_verify
(
"pear"
,
3
)
@skip
(
"scroll to tag functionality is removed"
)
def
test_scroll_to_tag_course_structure
(
self
):
def
test_scroll_to_tag_course_structure
(
self
):
"""
"""
Scenario: Can scroll to a tag group from the Course Structure view
Scenario: Can scroll to a tag group from the Course Structure view
...
@@ -872,6 +875,7 @@ class EdxNotesPageTest(EventsTestMixin, EdxNotesTestMixin):
...
@@ -872,6 +875,7 @@ class EdxNotesPageTest(EventsTestMixin, EdxNotesTestMixin):
self
.
notes_page
.
visit
()
.
switch_to_tab
(
"structure"
)
self
.
notes_page
.
visit
()
.
switch_to_tab
(
"structure"
)
self
.
_scroll_to_tag_and_verify
(
"squash"
,
5
)
self
.
_scroll_to_tag_and_verify
(
"squash"
,
5
)
@skip
(
"scroll to tag functionality is removed"
)
def
test_scroll_to_tag_search
(
self
):
def
test_scroll_to_tag_search
(
self
):
"""
"""
Scenario: Can scroll to a tag group from the Search Results view
Scenario: Can scroll to a tag group from the Search Results view
...
@@ -884,6 +888,7 @@ class EdxNotesPageTest(EventsTestMixin, EdxNotesTestMixin):
...
@@ -884,6 +888,7 @@ class EdxNotesPageTest(EventsTestMixin, EdxNotesTestMixin):
self
.
notes_page
.
visit
()
.
search
(
"note"
)
self
.
notes_page
.
visit
()
.
search
(
"note"
)
self
.
_scroll_to_tag_and_verify
(
"pumpkin"
,
4
)
self
.
_scroll_to_tag_and_verify
(
"pumpkin"
,
4
)
@skip
(
"scroll to tag functionality is removed"
)
def
test_scroll_to_tag_from_tag_view
(
self
):
def
test_scroll_to_tag_from_tag_view
(
self
):
"""
"""
Scenario: Can scroll to a tag group from the Tags view
Scenario: Can scroll to a tag group from the Tags view
...
...
lms/djangoapps/edxnotes/helpers.py
View file @
13b14e0a
...
@@ -106,6 +106,7 @@ def send_request(user, course_id, page, page_size, path="", text=None):
...
@@ -106,6 +106,7 @@ def send_request(user, course_id, page, page_size, path="", text=None):
params
=
params
params
=
params
)
)
except
RequestException
:
except
RequestException
:
log
.
error
(
"Failed to connect to edx-notes-api: url=
%
s, params=
%
s"
,
url
,
str
(
params
))
raise
EdxNotesServiceUnavailable
(
_
(
"EdxNotes Service is unavailable. Please try again in a few minutes."
))
raise
EdxNotesServiceUnavailable
(
_
(
"EdxNotes Service is unavailable. Please try again in a few minutes."
))
return
response
return
response
...
@@ -141,6 +142,7 @@ def preprocess_collection(user, course, collection):
...
@@ -141,6 +142,7 @@ def preprocess_collection(user, course, collection):
store
=
modulestore
()
store
=
modulestore
()
filtered_collection
=
list
()
filtered_collection
=
list
()
cache
=
{}
cache
=
{}
include_extra_info
=
settings
.
NOTES_DISABLED_TABS
==
[]
with
store
.
bulk_operations
(
course
.
id
):
with
store
.
bulk_operations
(
course
.
id
):
for
model
in
collection
:
for
model
in
collection
:
update
=
{
update
=
{
...
@@ -176,42 +178,46 @@ def preprocess_collection(user, course, collection):
...
@@ -176,42 +178,46 @@ def preprocess_collection(user, course, collection):
log
.
debug
(
"Unit not found:
%
s"
,
usage_key
)
log
.
debug
(
"Unit not found:
%
s"
,
usage_key
)
continue
continue
section
=
unit
.
get_parent
()
if
include_extra_info
:
if
not
section
:
section
=
unit
.
get_parent
()
log
.
debug
(
"Section not found:
%
s"
,
usage_key
)
if
not
section
:
continue
log
.
debug
(
"Section not found:
%
s"
,
usage_key
)
if
section
in
cache
:
continue
usage_context
=
cache
[
section
]
if
section
in
cache
:
usage_context
.
update
({
usage_context
=
cache
[
section
]
"unit"
:
get_module_context
(
course
,
unit
),
usage_context
.
update
({
})
"unit"
:
get_module_context
(
course
,
unit
),
model
.
update
(
usage_context
)
})
cache
[
usage_id
]
=
cache
[
unit
]
=
usage_context
model
.
update
(
usage_context
)
filtered_collection
.
append
(
model
)
cache
[
usage_id
]
=
cache
[
unit
]
=
usage_context
continue
filtered_collection
.
append
(
model
)
continue
chapter
=
section
.
get_parent
()
if
not
chapter
:
chapter
=
section
.
get_parent
()
log
.
debug
(
"Chapter not found:
%
s"
,
usage_key
)
if
not
chapter
:
continue
log
.
debug
(
"Chapter not found:
%
s"
,
usage_key
)
if
chapter
in
cache
:
continue
usage_context
=
cache
[
chapter
]
if
chapter
in
cache
:
usage_context
.
update
({
usage_context
=
cache
[
chapter
]
"unit"
:
get_module_context
(
course
,
unit
),
usage_context
.
update
({
"section"
:
get_module_context
(
course
,
section
),
"unit"
:
get_module_context
(
course
,
unit
),
})
"section"
:
get_module_context
(
course
,
section
),
model
.
update
(
usage_context
)
})
cache
[
usage_id
]
=
cache
[
unit
]
=
cache
[
section
]
=
usage_context
model
.
update
(
usage_context
)
filtered_collection
.
append
(
model
)
cache
[
usage_id
]
=
cache
[
unit
]
=
cache
[
section
]
=
usage_context
continue
filtered_collection
.
append
(
model
)
continue
usage_context
=
{
usage_context
=
{
"unit"
:
get_module_context
(
course
,
unit
),
"unit"
:
get_module_context
(
course
,
unit
),
"section"
:
get_module_context
(
course
,
section
),
"section"
:
get_module_context
(
course
,
section
)
if
include_extra_info
else
{}
,
"chapter"
:
get_module_context
(
course
,
chapter
),
"chapter"
:
get_module_context
(
course
,
chapter
)
if
include_extra_info
else
{}
,
}
}
model
.
update
(
usage_context
)
model
.
update
(
usage_context
)
cache
[
usage_id
]
=
cache
[
unit
]
=
cache
[
section
]
=
cache
[
chapter
]
=
usage_context
if
include_extra_info
:
cache
[
section
]
=
cache
[
chapter
]
=
usage_context
cache
[
usage_id
]
=
cache
[
unit
]
=
usage_context
filtered_collection
.
append
(
model
)
filtered_collection
.
append
(
model
)
return
filtered_collection
return
filtered_collection
...
@@ -319,16 +325,24 @@ def get_notes(request, course, page=DEFAULT_PAGE, page_size=DEFAULT_PAGE_SIZE, t
...
@@ -319,16 +325,24 @@ def get_notes(request, course, page=DEFAULT_PAGE, page_size=DEFAULT_PAGE_SIZE, t
try
:
try
:
collection
=
json
.
loads
(
response
.
content
)
collection
=
json
.
loads
(
response
.
content
)
except
ValueError
:
except
ValueError
:
raise
EdxNotesParseError
(
_
(
"Invalid response received from notes api."
))
log
.
error
(
"Invalid JSON response received from notes api: response_content=
%
s"
,
response
.
content
)
raise
EdxNotesParseError
(
_
(
"Invalid JSON response received from notes api."
))
# Verify response dict structure
# Verify response dict structure
expected_keys
=
[
'
count'
,
'result
s'
,
'num_pages'
,
'start'
,
'next'
,
'previous'
,
'current_page'
]
expected_keys
=
[
'
total'
,
'row
s'
,
'num_pages'
,
'start'
,
'next'
,
'previous'
,
'current_page'
]
keys
=
collection
.
keys
()
keys
=
collection
.
keys
()
if
not
keys
or
not
all
(
key
in
expected_keys
for
key
in
keys
):
if
not
keys
or
not
all
(
key
in
expected_keys
for
key
in
keys
):
raise
EdxNotesParseError
(
_
(
"Invalid response received from notes api."
))
log
.
error
(
"Incorrect data received from notes api: collection_data=
%
s"
,
str
(
collection
))
raise
EdxNotesParseError
(
_
(
"Incorrect data received from notes api."
))
filtered_results
=
preprocess_collection
(
request
.
user
,
course
,
collection
[
'results'
])
filtered_results
=
preprocess_collection
(
request
.
user
,
course
,
collection
[
'rows'
])
# Notes API is called from:
# 1. The annotatorjs in courseware. It expects these attributes to be named "total" and "rows".
# 2. The Notes tab Javascript proxied through LMS. It expects these attributes to be called "count" and "results".
collection
[
'count'
]
=
collection
[
'total'
]
del
collection
[
'total'
]
collection
[
'results'
]
=
filtered_results
collection
[
'results'
]
=
filtered_results
del
collection
[
'rows'
]
collection
[
'next'
],
collection
[
'previous'
]
=
construct_pagination_urls
(
collection
[
'next'
],
collection
[
'previous'
]
=
construct_pagination_urls
(
request
,
request
,
...
...
lms/djangoapps/edxnotes/tests.py
View file @
13b14e0a
...
@@ -33,6 +33,16 @@ from student.tests.factories import UserFactory, CourseEnrollmentFactory
...
@@ -33,6 +33,16 @@ from student.tests.factories import UserFactory, CourseEnrollmentFactory
NOTES_API_EMPTY_RESPONSE
=
{
NOTES_API_EMPTY_RESPONSE
=
{
"total"
:
0
,
"rows"
:
[],
"current_page"
:
1
,
"start"
:
0
,
"next"
:
None
,
"previous"
:
None
,
"num_pages"
:
0
,
}
NOTES_VIEW_EMPTY_RESPONSE
=
{
"count"
:
0
,
"count"
:
0
,
"results"
:
[],
"results"
:
[],
"current_page"
:
1
,
"current_page"
:
1
,
...
@@ -297,13 +307,13 @@ class EdxNotesHelpersTest(ModuleStoreTestCase):
...
@@ -297,13 +307,13 @@ class EdxNotesHelpersTest(ModuleStoreTestCase):
"""
"""
mock_get
.
return_value
.
content
=
json
.
dumps
(
mock_get
.
return_value
.
content
=
json
.
dumps
(
{
{
"
count
"
:
2
,
"
total
"
:
2
,
"current_page"
:
1
,
"current_page"
:
1
,
"start"
:
0
,
"start"
:
0
,
"next"
:
None
,
"next"
:
None
,
"previous"
:
None
,
"previous"
:
None
,
"num_pages"
:
1
,
"num_pages"
:
1
,
"r
esult
s"
:
[
"r
ow
s"
:
[
{
{
u"quote"
:
u"quote text"
,
u"quote"
:
u"quote text"
,
u"text"
:
u"text"
,
u"text"
:
u"text"
,
...
@@ -404,13 +414,13 @@ class EdxNotesHelpersTest(ModuleStoreTestCase):
...
@@ -404,13 +414,13 @@ class EdxNotesHelpersTest(ModuleStoreTestCase):
Tests the result if correct data is received.
Tests the result if correct data is received.
"""
"""
mock_get
.
return_value
.
content
=
json
.
dumps
({
mock_get
.
return_value
.
content
=
json
.
dumps
({
"
count
"
:
2
,
"
total
"
:
2
,
"current_page"
:
1
,
"current_page"
:
1
,
"start"
:
0
,
"start"
:
0
,
"next"
:
None
,
"next"
:
None
,
"previous"
:
None
,
"previous"
:
None
,
"num_pages"
:
1
,
"num_pages"
:
1
,
"r
esult
s"
:
[
"r
ow
s"
:
[
{
{
u"quote"
:
u"quote text"
,
u"quote"
:
u"quote text"
,
u"text"
:
u"text"
,
u"text"
:
u"text"
,
...
@@ -511,7 +521,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase):
...
@@ -511,7 +521,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase):
"""
"""
mock_get
.
return_value
.
content
=
json
.
dumps
(
NOTES_API_EMPTY_RESPONSE
)
mock_get
.
return_value
.
content
=
json
.
dumps
(
NOTES_API_EMPTY_RESPONSE
)
self
.
assertItemsEqual
(
self
.
assertItemsEqual
(
NOTES_
API
_EMPTY_RESPONSE
,
NOTES_
VIEW
_EMPTY_RESPONSE
,
json
.
loads
(
helpers
.
get_notes
(
self
.
request
,
self
.
course
))
json
.
loads
(
helpers
.
get_notes
(
self
.
request
,
self
.
course
))
)
)
...
@@ -1006,19 +1016,17 @@ class EdxNotesViewsTest(ModuleStoreTestCase):
...
@@ -1006,19 +1016,17 @@ class EdxNotesViewsTest(ModuleStoreTestCase):
"""
"""
Tests that search notes successfully respond if EdxNotes feature is enabled.
Tests that search notes successfully respond if EdxNotes feature is enabled.
"""
"""
mock_search
.
return_value
=
json
.
dumps
(
NOTES_
API
_EMPTY_RESPONSE
)
mock_search
.
return_value
=
json
.
dumps
(
NOTES_
VIEW
_EMPTY_RESPONSE
)
enable_edxnotes_for_the_course
(
self
.
course
,
self
.
user
.
id
)
enable_edxnotes_for_the_course
(
self
.
course
,
self
.
user
.
id
)
response
=
self
.
client
.
get
(
self
.
notes_url
,
{
"text"
:
"test"
})
response
=
self
.
client
.
get
(
self
.
notes_url
,
{
"text"
:
"test"
})
self
.
assertEqual
(
json
.
loads
(
response
.
content
),
NOTES_
API
_EMPTY_RESPONSE
)
self
.
assertEqual
(
json
.
loads
(
response
.
content
),
NOTES_
VIEW
_EMPTY_RESPONSE
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
status_code
,
200
)
@patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_EDXNOTES"
:
False
})
@patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_EDXNOTES"
:
False
})
@patch
(
"edxnotes.views.get_notes"
,
autospec
=
True
)
def
test_search_notes_is_disabled
(
self
):
def
test_search_notes_is_disabled
(
self
,
mock_search
):
"""
"""
Tests that 404 status code is received if EdxNotes feature is disabled.
Tests that 404 status code is received if EdxNotes feature is disabled.
"""
"""
mock_search
.
return_value
=
json
.
dumps
(
NOTES_API_EMPTY_RESPONSE
)
response
=
self
.
client
.
get
(
self
.
notes_url
,
{
"text"
:
"test"
})
response
=
self
.
client
.
get
(
self
.
notes_url
,
{
"text"
:
"test"
})
self
.
assertEqual
(
response
.
status_code
,
404
)
self
.
assertEqual
(
response
.
status_code
,
404
)
...
...
lms/djangoapps/edxnotes/views.py
View file @
13b14e0a
...
@@ -55,8 +55,10 @@ def edxnotes(request, course_id):
...
@@ -55,8 +55,10 @@ def edxnotes(request, course_id):
"course"
:
course
,
"course"
:
course
,
"notes_endpoint"
:
reverse
(
"notes"
,
kwargs
=
{
"course_id"
:
course_id
}),
"notes_endpoint"
:
reverse
(
"notes"
,
kwargs
=
{
"course_id"
:
course_id
}),
"notes"
:
notes_info
,
"notes"
:
notes_info
,
"page_size"
:
DEFAULT_PAGE_SIZE
,
"debug"
:
json
.
dumps
(
settings
.
DEBUG
),
"debug"
:
json
.
dumps
(
settings
.
DEBUG
),
'position'
:
None
,
'position'
:
None
,
'disabled_tabs'
:
settings
.
NOTES_DISABLED_TABS
,
}
}
if
len
(
json
.
loads
(
notes_info
)[
'results'
])
==
0
:
if
len
(
json
.
loads
(
notes_info
)[
'results'
])
==
0
:
...
...
lms/envs/bok_choy.py
View file @
13b14e0a
...
@@ -91,6 +91,8 @@ XQUEUE_INTERFACE['url'] = 'http://localhost:8040'
...
@@ -91,6 +91,8 @@ XQUEUE_INTERFACE['url'] = 'http://localhost:8040'
EDXNOTES_PUBLIC_API
=
'http://localhost:8042/api/v1'
EDXNOTES_PUBLIC_API
=
'http://localhost:8042/api/v1'
EDXNOTES_INTERNAL_API
=
'http://localhost:8042/api/v1'
EDXNOTES_INTERNAL_API
=
'http://localhost:8042/api/v1'
NOTES_DISABLED_TABS
=
[]
# Silence noisy logs
# Silence noisy logs
import
logging
import
logging
LOG_OVERRIDES
=
[
LOG_OVERRIDES
=
[
...
...
lms/envs/common.py
View file @
13b14e0a
...
@@ -2521,6 +2521,9 @@ ENROLLMENT_COURSE_DETAILS_CACHE_TIMEOUT = 60
...
@@ -2521,6 +2521,9 @@ ENROLLMENT_COURSE_DETAILS_CACHE_TIMEOUT = 60
if
FEATURES
[
'ENABLE_EDXNOTES'
]:
if
FEATURES
[
'ENABLE_EDXNOTES'
]:
OAUTH_ID_TOKEN_EXPIRATION
=
60
*
60
OAUTH_ID_TOKEN_EXPIRATION
=
60
*
60
# These tabs are currently disabled
NOTES_DISABLED_TABS
=
[
'course_structure'
,
'tags'
]
# Configuration used for generating PDF Receipts/Invoices
# Configuration used for generating PDF Receipts/Invoices
PDF_RECEIPT_TAX_ID
=
'add here'
PDF_RECEIPT_TAX_ID
=
'add here'
PDF_RECEIPT_FOOTER_TEXT
=
'add your own specific footer text here'
PDF_RECEIPT_FOOTER_TEXT
=
'add your own specific footer text here'
...
...
lms/envs/test.py
View file @
13b14e0a
...
@@ -509,6 +509,8 @@ MONGODB_LOG = {
...
@@ -509,6 +509,8 @@ MONGODB_LOG = {
'db'
:
'xlog'
,
'db'
:
'xlog'
,
}
}
NOTES_DISABLED_TABS
=
[]
# Enable EdxNotes for tests.
# Enable EdxNotes for tests.
FEATURES
[
'ENABLE_EDXNOTES'
]
=
True
FEATURES
[
'ENABLE_EDXNOTES'
]
=
True
...
...
lms/static/js/edxnotes/collections/notes.js
View file @
13b14e0a
;(
function
(
define
,
undefined
)
{
;(
function
(
define
)
{
'use strict'
;
'use strict'
;
define
([
define
([
'
backbone
'
,
'js/edxnotes/models/note'
'
underscore'
,
'common/js/components/collections/paging_collection
'
,
'js/edxnotes/models/note'
],
function
(
Backbone
,
NoteModel
)
{
],
function
(
_
,
PagingCollection
,
NoteModel
)
{
var
NotesCollection
=
Backbone
.
Collection
.
extend
({
return
Paging
Collection
.
extend
({
model
:
NoteModel
,
model
:
NoteModel
,
initialize
:
function
(
models
,
options
)
{
PagingCollection
.
prototype
.
initialize
.
call
(
this
);
this
.
perPage
=
options
.
perPage
;
this
.
server_api
=
_
.
pick
(
PagingCollection
.
prototype
.
server_api
,
"page"
,
"page_size"
);
if
(
options
.
text
)
{
this
.
server_api
.
text
=
options
.
text
;
}
},
/**
/**
* Returns course structure from the list of notes.
* Returns course structure from the list of notes.
* @return {Object}
* @return {Object}
...
@@ -17,30 +27,26 @@ define([
...
@@ -17,30 +27,26 @@ define([
sections
=
{},
sections
=
{},
units
=
{};
units
=
{};
if
(
!
courseStructure
)
{
this
.
each
(
function
(
note
)
{
this
.
each
(
function
(
note
)
{
var
chapter
=
note
.
get
(
'chapter'
),
var
chapter
=
note
.
get
(
'chapter'
),
section
=
note
.
get
(
'section'
),
section
=
note
.
get
(
'section'
),
unit
=
note
.
get
(
'unit'
);
unit
=
note
.
get
(
'unit'
);
chapters
[
chapter
.
location
]
=
chapter
;
chapters
[
chapter
.
location
]
=
chapter
;
sections
[
section
.
location
]
=
section
;
sections
[
section
.
location
]
=
section
;
units
[
unit
.
location
]
=
units
[
unit
.
location
]
||
[];
units
[
unit
.
location
]
=
units
[
unit
.
location
]
||
[];
units
[
unit
.
location
].
push
(
note
);
units
[
unit
.
location
].
push
(
note
);
});
});
courseStructure
=
{
courseStructure
=
{
chapters
:
_
.
sortBy
(
_
.
toArray
(
chapters
),
function
(
c
)
{
return
c
.
index
;}),
chapters
:
_
.
sortBy
(
_
.
toArray
(
chapters
),
function
(
c
)
{
return
c
.
index
;}),
sections
:
sections
,
sections
:
sections
,
units
:
units
units
:
units
};
};
}
return
courseStructure
;
return
courseStructure
;
};
};
}())
}())
});
});
return
NotesCollection
;
});
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/edxnotes/views/notes_page.js
View file @
13b14e0a
...
@@ -15,17 +15,19 @@ define([
...
@@ -15,17 +15,19 @@ define([
this
.
options
=
options
;
this
.
options
=
options
;
this
.
tabsCollection
=
new
TabsCollection
();
this
.
tabsCollection
=
new
TabsCollection
();
// Must create the Tags view first to get the "scrollToTag" method.
if
(
!
_
.
contains
(
this
.
options
.
disabledTabs
,
'tags'
))
{
this
.
tagsView
=
new
TagsView
({
// Must create the Tags view first to get the "scrollToTag" method.
el
:
this
.
el
,
this
.
tagsView
=
new
TagsView
({
collection
:
this
.
collection
,
el
:
this
.
el
,
tabsCollection
:
this
.
tabsCollection
collection
:
this
.
collection
,
});
tabsCollection
:
this
.
tabsCollection
});
scrollToTag
=
this
.
tagsView
.
scrollToTag
;
scrollToTag
=
this
.
tagsView
.
scrollToTag
;
// Remove the Tags model from the tabs collection because it should not appear first.
// Remove the Tags model from the tabs collection because it should not appear first.
tagsModel
=
this
.
tabsCollection
.
shift
();
tagsModel
=
this
.
tabsCollection
.
shift
();
}
this
.
recentActivityView
=
new
RecentActivityView
({
this
.
recentActivityView
=
new
RecentActivityView
({
el
:
this
.
el
,
el
:
this
.
el
,
...
@@ -34,20 +36,23 @@ define([
...
@@ -34,20 +36,23 @@ define([
scrollToTag
:
scrollToTag
scrollToTag
:
scrollToTag
});
});
this
.
courseStructureView
=
new
CourseStructureView
({
if
(
!
_
.
contains
(
this
.
options
.
disabledTabs
,
'course_structure'
))
{
el
:
this
.
el
,
this
.
courseStructureView
=
new
CourseStructureView
({
collection
:
this
.
collection
,
el
:
this
.
el
,
tabsCollection
:
this
.
tabsCollection
,
collection
:
this
.
collection
,
scrollToTag
:
scrollToTag
tabsCollection
:
this
.
tabsCollection
,
});
scrollToTag
:
scrollToTag
});
// Add the Tags model after the Course Structure model.
// Add the Tags model after the Course Structure model.
this
.
tabsCollection
.
push
(
tagsModel
);
this
.
tabsCollection
.
push
(
tagsModel
);
}
this
.
searchResultsView
=
new
SearchResultsView
({
this
.
searchResultsView
=
new
SearchResultsView
({
el
:
this
.
el
,
el
:
this
.
el
,
tabsCollection
:
this
.
tabsCollection
,
tabsCollection
:
this
.
tabsCollection
,
debug
:
this
.
options
.
debug
,
debug
:
this
.
options
.
debug
,
perPage
:
this
.
options
.
perPage
,
createTabOnInitialization
:
false
,
createTabOnInitialization
:
false
,
scrollToTag
:
scrollToTag
scrollToTag
:
scrollToTag
});
});
...
...
lms/static/js/edxnotes/views/page_factory.js
View file @
13b14e0a
...
@@ -6,19 +6,30 @@ define([
...
@@ -6,19 +6,30 @@ define([
/**
/**
* Factory method for the Notes page.
* Factory method for the Notes page.
* @param {Object} params Params for the Notes page.
* @param {Object} params Params for the Notes page.
* @param {Array} params.notesList A list of note models.
* @param {List} params.disabledTabs Names of disabled tabs, these tabs will not be shown.
* @param {Object} params.notes Paginated notes info.
* @param {Number} params.pageSize Number of notes per page.
* @param {Boolean} params.debugMode Enable the flag to see debug information.
* @param {Boolean} params.debugMode Enable the flag to see debug information.
* @param {String} params.endpoint The endpoint of the store.
* @param {String} params.endpoint The endpoint of the store.
* @return {Object} An instance of NotesPageView.
* @return {Object} An instance of NotesPageView.
*/
*/
return
function
(
params
)
{
return
function
(
params
)
{
var
collection
=
new
NotesCollection
(
params
.
notesList
);
var
collection
=
new
NotesCollection
(
params
.
notes
,
{
url
:
params
.
notesEndpoint
,
perPage
:
params
.
pageSize
,
parse
:
true
}
);
return
new
NotesPageView
({
return
new
NotesPageView
({
el
:
$
(
'.wrapper-student-notes'
).
get
(
0
),
el
:
$
(
'.wrapper-student-notes'
).
get
(
0
),
collection
:
collection
,
collection
:
collection
,
debug
:
params
.
debugMode
,
debug
:
params
.
debugMode
,
endpoint
:
params
.
endpoint
endpoint
:
params
.
endpoint
,
perPage
:
params
.
pageSize
,
disabledTabs
:
params
.
disabledTabs
});
});
};
};
});
});
...
...
lms/static/js/edxnotes/views/search_box.js
View file @
13b14e0a
...
@@ -43,15 +43,12 @@ define([
...
@@ -43,15 +43,12 @@ define([
* @return {Array}
* @return {Array}
*/
*/
prepareData
:
function
(
data
)
{
prepareData
:
function
(
data
)
{
var
collection
;
if
(
!
(
data
&&
_
.
has
(
data
,
'count'
)
&&
_
.
has
(
data
,
'results'
)))
{
if
(
!
(
data
&&
_
.
has
(
data
,
'total'
)
&&
_
.
has
(
data
,
'rows'
)))
{
this
.
logger
.
log
(
'Wrong data'
,
data
,
this
.
searchQuery
);
this
.
logger
.
log
(
'Wrong data'
,
data
,
this
.
searchQuery
);
return
null
;
return
null
;
}
}
collection
=
new
NotesCollection
(
data
.
rows
);
return
[
this
.
collection
,
this
.
searchQuery
];
return
[
collection
,
data
.
total
,
this
.
searchQuery
];
},
},
/**
/**
...
@@ -99,8 +96,8 @@ define([
...
@@ -99,8 +96,8 @@ define([
if
(
args
)
{
if
(
args
)
{
this
.
options
.
search
.
apply
(
this
,
args
);
this
.
options
.
search
.
apply
(
this
,
args
);
this
.
logger
.
emit
(
'edx.course.student_notes.searched'
,
{
this
.
logger
.
emit
(
'edx.course.student_notes.searched'
,
{
'number_of_results'
:
args
[
1
]
,
'number_of_results'
:
args
[
0
].
totalCount
,
'search_string'
:
args
[
2
]
'search_string'
:
args
[
1
]
});
});
}
else
{
}
else
{
this
.
options
.
error
(
this
.
errorMessage
,
this
.
searchQuery
);
this
.
options
.
error
(
this
.
errorMessage
,
this
.
searchQuery
);
...
@@ -144,15 +141,15 @@ define([
...
@@ -144,15 +141,15 @@ define([
* @return {jQuery.Deferred}
* @return {jQuery.Deferred}
*/
*/
sendRequest
:
function
(
text
)
{
sendRequest
:
function
(
text
)
{
var
settings
=
{
this
.
collection
=
new
NotesCollection
(
url
:
this
.
el
.
action
,
[]
,
type
:
this
.
el
.
method
,
{
dataType
:
'json'
,
text
:
text
,
data
:
{
text
:
text
}
perPage
:
this
.
options
.
perPage
,
};
url
:
this
.
el
.
action
}
this
.
logger
.
log
(
settings
);
);
return
$
.
ajax
(
settings
);
return
this
.
collection
.
goTo
(
1
);
}
}
});
});
...
...
lms/static/js/edxnotes/views/tab_panel.js
View file @
13b14e0a
;(
function
(
define
,
undefined
)
{
;(
function
(
define
,
undefined
)
{
'use strict'
;
'use strict'
;
define
([
'gettext'
,
'underscore'
,
'backbone'
,
'js/edxnotes/views/note_item'
],
define
([
'gettext'
,
'underscore'
,
'backbone'
,
'js/edxnotes/views/note_item'
,
function
(
gettext
,
_
,
Backbone
,
NoteItemView
)
{
'common/js/components/views/paging_header'
,
'common/js/components/views/paging_footer'
],
function
(
gettext
,
_
,
Backbone
,
NoteItemView
,
PagingHeaderView
,
PagingFooterView
)
{
var
TabPanelView
=
Backbone
.
View
.
extend
({
var
TabPanelView
=
Backbone
.
View
.
extend
({
tagName
:
'section'
,
tagName
:
'section'
,
className
:
'tab-panel'
,
className
:
'tab-panel'
,
...
@@ -13,14 +14,30 @@ function (gettext, _, Backbone, NoteItemView) {
...
@@ -13,14 +14,30 @@ function (gettext, _, Backbone, NoteItemView) {
initialize
:
function
()
{
initialize
:
function
()
{
this
.
children
=
[];
this
.
children
=
[];
if
(
this
.
options
.
createHeaderFooter
)
{
this
.
pagingHeaderView
=
new
PagingHeaderView
({
collection
:
this
.
collection
});
this
.
pagingFooterView
=
new
PagingFooterView
({
collection
:
this
.
collection
});
}
if
(
this
.
hasOwnProperty
(
'collection'
))
{
this
.
listenTo
(
this
.
collection
,
'page_changed'
,
this
.
render
);
}
},
},
render
:
function
()
{
render
:
function
()
{
this
.
$el
.
html
(
this
.
getTitle
());
this
.
$el
.
html
(
this
.
getTitle
());
this
.
renderView
(
this
.
pagingHeaderView
);
this
.
renderContent
();
this
.
renderContent
();
this
.
renderView
(
this
.
pagingFooterView
);
return
this
;
return
this
;
},
},
renderView
:
function
(
view
)
{
if
(
this
.
options
.
createHeaderFooter
&&
this
.
collection
.
models
.
length
)
{
this
.
$el
.
append
(
view
.
render
().
el
);
view
.
delegateEvents
();
}
},
renderContent
:
function
()
{
renderContent
:
function
()
{
return
this
;
return
this
;
},
},
...
...
lms/static/js/edxnotes/views/tab_view.js
View file @
13b14e0a
...
@@ -14,7 +14,8 @@ define([
...
@@ -14,7 +14,8 @@ define([
initialize
:
function
(
options
)
{
initialize
:
function
(
options
)
{
_
.
bindAll
(
this
,
'showLoadingIndicator'
,
'hideLoadingIndicator'
);
_
.
bindAll
(
this
,
'showLoadingIndicator'
,
'hideLoadingIndicator'
);
this
.
options
=
_
.
defaults
(
options
||
{},
{
this
.
options
=
_
.
defaults
(
options
||
{},
{
createTabOnInitialization
:
true
createTabOnInitialization
:
true
,
createHeaderFooter
:
true
});
});
if
(
this
.
options
.
createTabOnInitialization
)
{
if
(
this
.
options
.
createTabOnInitialization
)
{
...
@@ -64,7 +65,13 @@ define([
...
@@ -64,7 +65,13 @@ define([
getSubView
:
function
()
{
getSubView
:
function
()
{
var
collection
=
this
.
getCollection
();
var
collection
=
this
.
getCollection
();
return
new
this
.
PanelConstructor
({
collection
:
collection
,
scrollToTag
:
this
.
options
.
scrollToTag
});
return
new
this
.
PanelConstructor
(
{
collection
:
collection
,
scrollToTag
:
this
.
options
.
scrollToTag
,
createHeaderFooter
:
this
.
options
.
createHeaderFooter
}
);
},
},
destroySubView
:
function
()
{
destroySubView
:
function
()
{
...
...
lms/static/js/edxnotes/views/tabs/search_results.js
View file @
13b14e0a
...
@@ -58,6 +58,7 @@ define([
...
@@ -58,6 +58,7 @@ define([
this
.
searchBox
=
new
SearchBoxView
({
this
.
searchBox
=
new
SearchBoxView
({
el
:
document
.
getElementById
(
'search-notes-form'
),
el
:
document
.
getElementById
(
'search-notes-form'
),
debug
:
this
.
options
.
debug
,
debug
:
this
.
options
.
debug
,
perPage
:
this
.
options
.
perPage
,
beforeSearchStart
:
this
.
onBeforeSearchStart
,
beforeSearchStart
:
this
.
onBeforeSearchStart
,
search
:
this
.
onSearch
,
search
:
this
.
onSearch
,
error
:
this
.
onSearchError
error
:
this
.
onSearchError
...
@@ -81,7 +82,8 @@ define([
...
@@ -81,7 +82,8 @@ define([
return
new
this
.
PanelConstructor
({
return
new
this
.
PanelConstructor
({
collection
:
collection
,
collection
:
collection
,
searchQuery
:
this
.
searchResults
.
searchQuery
,
searchQuery
:
this
.
searchResults
.
searchQuery
,
scrollToTag
:
this
.
options
.
scrollToTag
scrollToTag
:
this
.
options
.
scrollToTag
,
createHeaderFooter
:
this
.
options
.
createHeaderFooter
});
});
}
else
{
}
else
{
return
new
this
.
NoResultsViewConstructor
({
return
new
this
.
NoResultsViewConstructor
({
...
@@ -122,10 +124,9 @@ define([
...
@@ -122,10 +124,9 @@ define([
}
}
},
},
onSearch
:
function
(
collection
,
total
,
searchQuery
)
{
onSearch
:
function
(
collection
,
searchQuery
)
{
this
.
searchResults
=
{
this
.
searchResults
=
{
collection
:
collection
,
collection
:
collection
,
total
:
total
,
searchQuery
:
searchQuery
searchQuery
:
searchQuery
};
};
...
...
lms/static/js/spec/edxnotes/collections/notes_spec.js
View file @
13b14e0a
...
@@ -6,7 +6,7 @@ define([
...
@@ -6,7 +6,7 @@ define([
var
notes
=
Helpers
.
getDefaultNotes
();
var
notes
=
Helpers
.
getDefaultNotes
();
beforeEach
(
function
()
{
beforeEach
(
function
()
{
this
.
collection
=
new
NotesCollection
(
notes
);
this
.
collection
=
new
NotesCollection
(
notes
,
{
perPage
:
10
,
parse
:
true
}
);
});
});
it
(
'can return correct course structure'
,
function
()
{
it
(
'can return correct course structure'
,
function
()
{
...
@@ -23,11 +23,22 @@ define([
...
@@ -23,11 +23,22 @@ define([
'i4x://section/2'
:
Helpers
.
getSection
(
'First Section'
,
2
,
[
3
])
'i4x://section/2'
:
Helpers
.
getSection
(
'First Section'
,
2
,
[
3
])
});
});
expect
(
structure
.
units
).
toEqual
({
var
compareUnits
=
function
(
structureUnits
,
collectionUnits
)
{
expect
(
structureUnits
.
length
===
collectionUnits
.
length
).
toBeTruthy
();
for
(
var
i
=
0
;
i
<
structureUnits
.
length
;
i
++
)
{
expect
(
structureUnits
[
i
].
attributes
).
toEqual
(
collectionUnits
[
i
].
attributes
);
}
};
var
units
=
{
'i4x://unit/0'
:
[
this
.
collection
.
at
(
0
),
this
.
collection
.
at
(
1
)],
'i4x://unit/0'
:
[
this
.
collection
.
at
(
0
),
this
.
collection
.
at
(
1
)],
'i4x://unit/1'
:
[
this
.
collection
.
at
(
2
)],
'i4x://unit/1'
:
[
this
.
collection
.
at
(
2
)],
'i4x://unit/2'
:
[
this
.
collection
.
at
(
3
)],
'i4x://unit/2'
:
[
this
.
collection
.
at
(
3
)],
'i4x://unit/3'
:
[
this
.
collection
.
at
(
4
)]
'i4x://unit/3'
:
[
this
.
collection
.
at
(
4
)]
};
_
.
each
(
units
,
function
(
value
,
key
){
compareUnits
(
structure
.
units
[
key
],
value
);
});
});
});
});
});
});
...
...
lms/static/js/spec/edxnotes/helpers.js
View file @
13b14e0a
define
([
'underscore'
],
function
(
_
)
{
define
([
'underscore'
,
'URI'
,
'common/js/spec_helpers/ajax_helpers'
],
function
(
_
,
URI
,
AjaxHelpers
)
{
'use strict'
;
'use strict'
;
var
B64
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
,
var
B64
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
,
LONG_TEXT
,
PRUNED_TEXT
,
TRUNCATED_TEXT
,
SHORT_TEXT
,
LONG_TEXT
,
PRUNED_TEXT
,
TRUNCATED_TEXT
,
SHORT_TEXT
,
base64Encode
,
makeToken
,
getChapter
,
getSection
,
getUnit
,
getDefaultNotes
;
base64Encode
,
makeToken
,
getChapter
,
getSection
,
getUnit
,
getDefaultNotes
,
verifyUrl
,
verifyRequestParams
,
createNotesData
,
respondToRequest
,
verifyPaginationInfo
,
verifyPageData
;
LONG_TEXT
=
[
LONG_TEXT
=
[
'Adipisicing elit, sed do eiusmod tempor incididunt '
,
'Adipisicing elit, sed do eiusmod tempor incididunt '
,
...
@@ -106,57 +108,131 @@ define(['underscore'], function(_) {
...
@@ -106,57 +108,131 @@ define(['underscore'], function(_) {
getDefaultNotes
=
function
()
{
getDefaultNotes
=
function
()
{
// Note that the server returns notes in reverse chronological order (newest first).
// Note that the server returns notes in reverse chronological order (newest first).
return
[
return
{
{
'count'
:
5
,
chapter
:
getChapter
(
'Second Chapter'
,
0
,
1
,
[
1
,
'w_n'
,
0
]),
'current_page'
:
1
,
section
:
getSection
(
'Third Section'
,
0
,
[
'w_n'
,
1
,
0
]),
'num_pages'
:
1
,
unit
:
getUnit
(
'Fourth Unit'
,
0
),
'start'
:
0
,
created
:
'December 11, 2014 at 11:12AM'
,
'next'
:
null
,
updated
:
'December 11, 2014 at 11:12AM'
,
'previous'
:
null
,
text
:
'Third added model'
,
'results'
:
[
quote
:
'Note 4'
,
{
tags
:
[
'Pumpkin'
,
'pumpkin'
,
'yummy'
]
chapter
:
getChapter
(
'Second Chapter'
,
0
,
1
,
[
1
,
'w_n'
,
0
]),
},
section
:
getSection
(
'Third Section'
,
0
,
[
'w_n'
,
1
,
0
]),
{
unit
:
getUnit
(
'Fourth Unit'
,
0
),
chapter
:
getChapter
(
'Second Chapter'
,
0
,
1
,
[
1
,
'w_n'
,
0
]),
created
:
'December 11, 2014 at 11:12AM'
,
section
:
getSection
(
'Third Section'
,
0
,
[
'w_n'
,
1
,
0
]),
updated
:
'December 11, 2014 at 11:12AM'
,
unit
:
getUnit
(
'Fourth Unit'
,
0
),
text
:
'Third added model'
,
created
:
'December 11, 2014 at 11:11AM'
,
quote
:
'Note 4'
,
updated
:
'December 11, 2014 at 11:11AM'
,
tags
:
[
'Pumpkin'
,
'pumpkin'
,
'yummy'
]
text
:
'Third added model'
,
},
quote
:
'Note 5'
{
},
chapter
:
getChapter
(
'Second Chapter'
,
0
,
1
,
[
1
,
'w_n'
,
0
]),
{
section
:
getSection
(
'Third Section'
,
0
,
[
'w_n'
,
1
,
0
]),
chapter
:
getChapter
(
'Second Chapter'
,
0
,
1
,
[
1
,
'w_n'
,
0
]),
unit
:
getUnit
(
'Fourth Unit'
,
0
),
section
:
getSection
(
'Third Section'
,
0
,
[
'w_n'
,
1
,
0
]),
created
:
'December 11, 2014 at 11:11AM'
,
unit
:
getUnit
(
'Third Unit'
,
1
),
updated
:
'December 11, 2014 at 11:11AM'
,
created
:
'December 11, 2014 at 11:11AM'
,
text
:
'Third added model'
,
updated
:
'December 11, 2014 at 11:11AM'
,
quote
:
'Note 5'
text
:
'Second added model'
,
},
quote
:
'Note 3'
,
{
tags
:
[
'yummy'
]
chapter
:
getChapter
(
'Second Chapter'
,
0
,
1
,
[
1
,
'w_n'
,
0
]),
},
section
:
getSection
(
'Third Section'
,
0
,
[
'w_n'
,
1
,
0
]),
{
unit
:
getUnit
(
'Third Unit'
,
1
),
chapter
:
getChapter
(
'Second Chapter'
,
0
,
1
,
[
1
,
'w_n'
,
0
]),
created
:
'December 11, 2014 at 11:11AM'
,
section
:
getSection
(
'Second Section'
,
1
,
[
2
]),
updated
:
'December 11, 2014 at 11:11AM'
,
unit
:
getUnit
(
'Second Unit'
,
2
),
text
:
'Second added model'
,
created
:
'December 11, 2014 at 11:10AM'
,
quote
:
'Note 3'
,
updated
:
'December 11, 2014 at 11:10AM'
,
tags
:
[
'yummy'
]
text
:
'First added model'
,
},
quote
:
'Note 2'
,
{
tags
:
[
'PUMPKIN'
,
'pie'
]
chapter
:
getChapter
(
'Second Chapter'
,
0
,
1
,
[
1
,
'w_n'
,
0
]),
},
section
:
getSection
(
'Second Section'
,
1
,
[
2
]),
{
unit
:
getUnit
(
'Second Unit'
,
2
),
chapter
:
getChapter
(
'First Chapter'
,
1
,
0
,
[
2
]),
created
:
'December 11, 2014 at 11:10AM'
,
section
:
getSection
(
'First Section'
,
2
,
[
3
]),
updated
:
'December 11, 2014 at 11:10AM'
,
unit
:
getUnit
(
'First Unit'
,
3
),
text
:
'First added model'
,
created
:
'December 11, 2014 at 11:10AM'
,
quote
:
'Note 2'
,
updated
:
'December 11, 2014 at 11:10AM'
,
tags
:
[
'PUMPKIN'
,
'pie'
]
text
:
'First added model'
,
},
quote
:
'Note 1'
,
{
tags
:
[
'pie'
,
'pumpkin'
]
chapter
:
getChapter
(
'First Chapter'
,
1
,
0
,
[
2
]),
}
section
:
getSection
(
'First Section'
,
2
,
[
3
]),
];
unit
:
getUnit
(
'First Unit'
,
3
),
created
:
'December 11, 2014 at 11:10AM'
,
updated
:
'December 11, 2014 at 11:10AM'
,
text
:
'First added model'
,
quote
:
'Note 1'
,
tags
:
[
'pie'
,
'pumpkin'
]
}
]
};
};
verifyUrl
=
function
(
requestUrl
,
expectedUrl
,
expectedParams
)
{
expect
(
requestUrl
.
slice
(
0
,
expectedUrl
.
length
)
===
expectedUrl
).
toBeTruthy
();
verifyRequestParams
(
requestUrl
,
expectedParams
);
};
verifyRequestParams
=
function
(
requestUrl
,
expectedParams
)
{
var
urlParams
=
(
new
URI
(
requestUrl
)).
query
(
true
);
_
.
each
(
expectedParams
,
function
(
value
,
key
)
{
expect
(
urlParams
[
key
]).
toBe
(
value
);
});
};
createNotesData
=
function
(
options
)
{
var
data
=
{
count
:
options
.
count
||
0
,
num_pages
:
options
.
num_pages
||
1
,
current_page
:
options
.
current_page
||
1
,
start
:
options
.
start
||
0
,
results
:
[]
};
for
(
var
i
=
0
;
i
<
options
.
numNotesToCreate
;
i
++
)
{
var
notesInfo
=
{
chapter
:
getChapter
(
'First Chapter__'
+
i
,
1
,
0
,
[
2
]),
section
:
getSection
(
'First Section__'
+
i
,
2
,
[
3
]),
unit
:
getUnit
(
'First Unit__'
+
i
,
3
),
created
:
new
Date
().
toISOString
(),
updated
:
new
Date
().
toISOString
(),
text
:
'text__'
+
i
,
quote
:
'Note__'
+
i
,
tags
:
[
'tag__'
+
i
,
'tag__'
+
i
+
1
]
};
data
.
results
.
push
(
notesInfo
);
}
return
data
;
};
respondToRequest
=
function
(
requests
,
responseJson
,
respondToEvent
)
{
// Respond to the analytics event
if
(
respondToEvent
)
{
AjaxHelpers
.
respondWithNoContent
(
requests
);
}
// Now process the actual request
AjaxHelpers
.
respondWithJson
(
requests
,
responseJson
);
};
verifyPaginationInfo
=
function
(
view
,
headerMessage
,
currentPage
,
totalPages
)
{
expect
(
view
.
$
(
'.search-count.listing-count'
).
text
().
trim
()).
toBe
(
headerMessage
);
expect
(
parseInt
(
view
.
$
(
'.pagination span.current-page'
).
text
().
trim
())).
toBe
(
currentPage
);
expect
(
parseInt
(
view
.
$
(
'.pagination span.total-pages'
).
text
().
trim
())).
toBe
(
totalPages
);
};
verifyPageData
=
function
(
view
,
tabsCollection
,
tabInfo
,
tabId
,
notes
)
{
expect
(
tabsCollection
).
toHaveLength
(
1
);
expect
(
tabsCollection
.
at
(
0
).
toJSON
()).
toEqual
(
tabInfo
);
expect
(
view
.
$
(
tabId
)).
toExist
();
expect
(
view
.
$
(
'.note'
)).
toHaveLength
(
notes
.
results
.
length
);
_
.
each
(
view
.
$
(
'.note'
),
function
(
element
,
index
)
{
expect
(
$
(
'.note-comments'
,
element
)).
toContainText
(
notes
.
results
[
index
].
text
);
expect
(
$
(
'.note-excerpt'
,
element
)).
toContainText
(
notes
.
results
[
index
].
quote
);
});
};
};
return
{
return
{
...
@@ -169,6 +245,12 @@ define(['underscore'], function(_) {
...
@@ -169,6 +245,12 @@ define(['underscore'], function(_) {
getChapter
:
getChapter
,
getChapter
:
getChapter
,
getSection
:
getSection
,
getSection
:
getSection
,
getUnit
:
getUnit
,
getUnit
:
getUnit
,
getDefaultNotes
:
getDefaultNotes
getDefaultNotes
:
getDefaultNotes
,
verifyUrl
:
verifyUrl
,
verifyRequestParams
:
verifyRequestParams
,
createNotesData
:
createNotesData
,
respondToRequest
:
respondToRequest
,
verifyPaginationInfo
:
verifyPaginationInfo
,
verifyPageData
:
verifyPageData
};
};
});
});
lms/static/js/spec/edxnotes/models/note_spec.js
View file @
13b14e0a
...
@@ -4,10 +4,23 @@ define([
...
@@ -4,10 +4,23 @@ define([
'use strict'
;
'use strict'
;
describe
(
'EdxNotes NoteModel'
,
function
()
{
describe
(
'EdxNotes NoteModel'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
this
.
collection
=
new
NotesCollection
([
this
.
collection
=
new
NotesCollection
(
{
quote
:
Helpers
.
LONG_TEXT
,
text
:
'text
\
n with
\
r
\
nline
\
n
\
rbreaks
\
r'
},
{
{
quote
:
Helpers
.
SHORT_TEXT
,
text
:
'text
\
n with
\
r
\
nline
\
n
\
rbreaks
\
r'
}
'count'
:
2
,
]);
'current_page'
:
1
,
'num_pages'
:
1
,
'start'
:
0
,
'next'
:
null
,
'previous'
:
null
,
'results'
:
[
{
quote
:
Helpers
.
LONG_TEXT
,
text
:
'text
\
n with
\
r
\
nline
\
n
\
rbreaks
\
r'
},
{
quote
:
Helpers
.
SHORT_TEXT
,
text
:
'text
\
n with
\
r
\
nline
\
n
\
rbreaks
\
r'
}
]
},
{
perPage
:
10
,
parse
:
true
}
);
});
});
it
(
'has correct values on initialization'
,
function
()
{
it
(
'has correct values on initialization'
,
function
()
{
...
...
lms/static/js/spec/edxnotes/views/note_item_spec.js
View file @
13b14e0a
...
@@ -67,12 +67,12 @@ define([
...
@@ -67,12 +67,12 @@ define([
var
view
=
getView
({
tags
:
[
"First"
,
"Second"
]});
var
view
=
getView
({
tags
:
[
"First"
,
"Second"
]});
expect
(
view
.
$
(
'.reference-title'
).
length
).
toBe
(
3
);
expect
(
view
.
$
(
'.reference-title'
).
length
).
toBe
(
3
);
expect
(
view
.
$
(
'.reference-title'
)[
2
]).
toContainText
(
'Tags:'
);
expect
(
view
.
$
(
'.reference-title'
)[
2
]).
toContainText
(
'Tags:'
);
expect
(
view
.
$
(
'
a
.reference-tags'
).
length
).
toBe
(
2
);
expect
(
view
.
$
(
'
span
.reference-tags'
).
length
).
toBe
(
2
);
expect
(
view
.
$
(
'
a
.reference-tags'
)[
0
]).
toContainText
(
'First'
);
expect
(
view
.
$
(
'
span
.reference-tags'
)[
0
]).
toContainText
(
'First'
);
expect
(
view
.
$
(
'
a
.reference-tags'
)[
1
]).
toContainText
(
'Second'
);
expect
(
view
.
$
(
'
span
.reference-tags'
)[
1
]).
toContainText
(
'Second'
);
});
});
it
(
'should handle a click event on the tag'
,
function
()
{
x
it
(
'should handle a click event on the tag'
,
function
()
{
var
scrollToTagSpy
=
{
var
scrollToTagSpy
=
{
scrollToTag
:
function
(
tagName
){}
scrollToTag
:
function
(
tagName
){}
};
};
...
...
lms/static/js/spec/edxnotes/views/notes_page_spec.js
View file @
13b14e0a
...
@@ -13,7 +13,7 @@ define([
...
@@ -13,7 +13,7 @@ define([
TemplateHelpers
.
installTemplates
([
TemplateHelpers
.
installTemplates
([
'templates/edxnotes/note-item'
,
'templates/edxnotes/tab-item'
'templates/edxnotes/note-item'
,
'templates/edxnotes/tab-item'
]);
]);
this
.
view
=
new
NotesFactory
({
notes
List
:
notes
});
this
.
view
=
new
NotesFactory
({
notes
:
notes
,
pageSize
:
10
});
});
});
...
@@ -35,8 +35,13 @@ define([
...
@@ -35,8 +35,13 @@ define([
this
.
view
.
$
(
'.search-notes-input'
).
val
(
'test_query'
);
this
.
view
.
$
(
'.search-notes-input'
).
val
(
'test_query'
);
this
.
view
.
$
(
'.search-notes-submit'
).
click
();
this
.
view
.
$
(
'.search-notes-submit'
).
click
();
AjaxHelpers
.
respondWithJson
(
requests
,
{
AjaxHelpers
.
respondWithJson
(
requests
,
{
total
:
0
,
'count'
:
0
,
rows
:
[]
'current_page'
:
1
,
'num_pages'
:
1
,
'start'
:
0
,
'next'
:
null
,
'previous'
:
null
,
'results'
:
[]
});
});
expect
(
this
.
view
.
$
(
'#view-search-results'
)).
toHaveClass
(
'is-active'
);
expect
(
this
.
view
.
$
(
'#view-search-results'
)).
toHaveClass
(
'is-active'
);
expect
(
this
.
view
.
$
(
'#view-recent-activity'
)).
toExist
();
expect
(
this
.
view
.
$
(
'#view-recent-activity'
)).
toExist
();
...
...
lms/static/js/spec/edxnotes/views/search_box_spec.js
View file @
13b14e0a
define
([
define
([
'jquery'
,
'underscore'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/edxnotes/views/search_box'
,
'jquery'
,
'underscore'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/edxnotes/views/search_box'
,
'js/edxnotes/collections/notes'
,
'js/spec/edxnotes/custom_matchers'
,
'jasmine-jquery'
'js/edxnotes/collections/notes'
,
'js/spec/edxnotes/custom_matchers'
,
'j
s/spec/edxnotes/helpers'
,
'j
asmine-jquery'
],
function
(
$
,
_
,
AjaxHelpers
,
SearchBoxView
,
NotesCollection
,
customMatchers
)
{
],
function
(
$
,
_
,
AjaxHelpers
,
SearchBoxView
,
NotesCollection
,
customMatchers
,
Helpers
)
{
'use strict'
;
'use strict'
;
describe
(
'EdxNotes SearchBoxView'
,
function
()
{
describe
(
'EdxNotes SearchBoxView'
,
function
()
{
var
getSearchBox
,
submitForm
,
assertBoxIsEnabled
,
assertBoxIsDisabled
;
var
getSearchBox
,
submitForm
,
assertBoxIsEnabled
,
assertBoxIsDisabled
,
searchResponse
;
searchResponse
=
{
'count'
:
2
,
'current_page'
:
1
,
'num_pages'
:
1
,
'start'
:
0
,
'next'
:
null
,
'previous'
:
null
,
'results'
:
[
null
,
null
]
};
getSearchBox
=
function
(
options
)
{
getSearchBox
=
function
(
options
)
{
options
=
_
.
defaults
(
options
||
{},
{
options
=
_
.
defaults
(
options
||
{},
{
el
:
$
(
'#search-notes-form'
).
get
(
0
),
el
:
$
(
'#search-notes-form'
).
get
(
0
),
perPage
:
10
,
beforeSearchStart
:
jasmine
.
createSpy
(),
beforeSearchStart
:
jasmine
.
createSpy
(),
search
:
jasmine
.
createSpy
(),
search
:
jasmine
.
createSpy
(),
error
:
jasmine
.
createSpy
(),
error
:
jasmine
.
createSpy
(),
...
@@ -50,7 +61,11 @@ define([
...
@@ -50,7 +61,11 @@ define([
submitForm
(
this
.
searchBox
,
'test_text'
);
submitForm
(
this
.
searchBox
,
'test_text'
);
request
=
requests
[
0
];
request
=
requests
[
0
];
expect
(
request
.
method
).
toBe
(
form
.
method
.
toUpperCase
());
expect
(
request
.
method
).
toBe
(
form
.
method
.
toUpperCase
());
expect
(
request
.
url
).
toBe
(
form
.
action
+
'?'
+
$
.
param
({
text
:
'test_text'
}));
Helpers
.
verifyUrl
(
request
.
url
,
form
.
action
,
{
text
:
'test_text'
,
page
:
'1'
,
page_size
:
'10'
}
);
});
});
it
(
'returns success result'
,
function
()
{
it
(
'returns success result'
,
function
()
{
...
@@ -60,13 +75,10 @@ define([
...
@@ -60,13 +75,10 @@ define([
'test_text'
'test_text'
);
);
assertBoxIsDisabled
(
this
.
searchBox
);
assertBoxIsDisabled
(
this
.
searchBox
);
AjaxHelpers
.
respondWithJson
(
requests
,
{
AjaxHelpers
.
respondWithJson
(
requests
,
searchResponse
);
total
:
2
,
rows
:
[
null
,
null
]
});
assertBoxIsEnabled
(
this
.
searchBox
);
assertBoxIsEnabled
(
this
.
searchBox
);
expect
(
this
.
searchBox
.
options
.
search
).
toHaveBeenCalledWith
(
expect
(
this
.
searchBox
.
options
.
search
).
toHaveBeenCalledWith
(
jasmine
.
any
(
NotesCollection
),
2
,
'test_text'
jasmine
.
any
(
NotesCollection
),
'test_text'
);
);
expect
(
this
.
searchBox
.
options
.
complete
).
toHaveBeenCalledWith
(
expect
(
this
.
searchBox
.
options
.
complete
).
toHaveBeenCalledWith
(
'test_text'
'test_text'
...
@@ -76,10 +88,7 @@ define([
...
@@ -76,10 +88,7 @@ define([
it
(
'should log the edx.course.student_notes.searched event properly'
,
function
()
{
it
(
'should log the edx.course.student_notes.searched event properly'
,
function
()
{
var
requests
=
AjaxHelpers
.
requests
(
this
);
var
requests
=
AjaxHelpers
.
requests
(
this
);
submitForm
(
this
.
searchBox
,
'test_text'
);
submitForm
(
this
.
searchBox
,
'test_text'
);
AjaxHelpers
.
respondWithJson
(
requests
,
{
AjaxHelpers
.
respondWithJson
(
requests
,
searchResponse
);
total
:
2
,
rows
:
[
null
,
null
]
});
expect
(
Logger
.
log
).
toHaveBeenCalledWith
(
'edx.course.student_notes.searched'
,
{
expect
(
Logger
.
log
).
toHaveBeenCalledWith
(
'edx.course.student_notes.searched'
,
{
'number_of_results'
:
2
,
'number_of_results'
:
2
,
...
@@ -140,10 +149,7 @@ define([
...
@@ -140,10 +149,7 @@ define([
submitForm
(
this
.
searchBox
,
'test_text'
);
submitForm
(
this
.
searchBox
,
'test_text'
);
assertBoxIsDisabled
(
this
.
searchBox
);
assertBoxIsDisabled
(
this
.
searchBox
);
submitForm
(
this
.
searchBox
,
'another_text'
);
submitForm
(
this
.
searchBox
,
'another_text'
);
AjaxHelpers
.
respondWithJson
(
requests
,
{
AjaxHelpers
.
respondWithJson
(
requests
,
searchResponse
);
total
:
2
,
rows
:
[
null
,
null
]
});
assertBoxIsEnabled
(
this
.
searchBox
);
assertBoxIsEnabled
(
this
.
searchBox
);
expect
(
requests
).
toHaveLength
(
1
);
expect
(
requests
).
toHaveLength
(
1
);
});
});
...
...
lms/static/js/spec/edxnotes/views/tabs/course_structure_spec.js
View file @
13b14e0a
...
@@ -40,7 +40,7 @@ define([
...
@@ -40,7 +40,7 @@ define([
'templates/edxnotes/note-item'
,
'templates/edxnotes/tab-item'
'templates/edxnotes/note-item'
,
'templates/edxnotes/tab-item'
]);
]);
this
.
collection
=
new
NotesCollection
(
notes
);
this
.
collection
=
new
NotesCollection
(
notes
,
{
perPage
:
10
,
parse
:
true
}
);
this
.
tabsCollection
=
new
TabsCollection
();
this
.
tabsCollection
=
new
TabsCollection
();
});
});
...
...
lms/static/js/spec/edxnotes/views/tabs/recent_activity_spec.js
View file @
13b14e0a
define
([
define
([
'jquery'
,
'common/js/spec_helpers/template_helpers'
,
'
js/edxnotes/collections/note
s'
,
'jquery'
,
'common/js/spec_helpers/template_helpers'
,
'
common/js/spec_helpers/ajax_helper
s'
,
'js/edxnotes/collections/tabs'
,
'js/edxnotes/views/tabs/recent_activity'
,
'js/edxnotes/collections/
notes'
,
'js/edxnotes/collections/
tabs'
,
'js/edxnotes/views/tabs/recent_activity'
,
'js/spec/edxnotes/custom_matchers'
,
'jasmine-jquery'
'js/spec/edxnotes/custom_matchers'
,
'j
s/spec/edxnotes/helpers'
,
'j
asmine-jquery'
],
function
(
],
function
(
$
,
TemplateHelpers
,
NotesCollection
,
TabsCollection
,
RecentActivityView
,
customMatch
ers
$
,
TemplateHelpers
,
AjaxHelpers
,
NotesCollection
,
TabsCollection
,
RecentActivityView
,
customMatchers
,
Help
ers
)
{
)
{
'use strict'
;
'use strict'
;
describe
(
'EdxNotes RecentActivityView'
,
function
()
{
describe
(
'EdxNotes RecentActivityView'
,
function
()
{
var
notes
=
[
var
notes
=
{
{
'count'
:
3
,
created
:
'December 11, 2014 at 11:12AM'
,
'current_page'
:
1
,
updated
:
'December 11, 2014 at 11:12AM'
,
'num_pages'
:
1
,
text
:
'Third added model'
,
'start'
:
0
,
quote
:
'Should be listed first'
'next'
:
null
,
},
'previous'
:
null
,
{
'results'
:
[
created
:
'December 11, 2014 at 11:11AM'
,
{
updated
:
'December 11, 2014 at 11:11AM'
,
created
:
'December 11, 2014 at 11:12AM'
,
text
:
'Second added model'
,
updated
:
'December 11, 2014 at 11:12AM'
,
quote
:
'Should be listed second'
text
:
'Third added model'
,
},
quote
:
'Should be listed first'
{
},
created
:
'December 11, 2014 at 11:10AM'
,
{
updated
:
'December 11, 2014 at 11:10AM'
,
created
:
'December 11, 2014 at 11:11AM'
,
text
:
'First added model'
,
updated
:
'December 11, 2014 at 11:11AM'
,
quote
:
'Should be listed third'
text
:
'Second added model'
,
}
quote
:
'Should be listed second'
],
getView
;
},
{
created
:
'December 11, 2014 at 11:10AM'
,
updated
:
'December 11, 2014 at 11:10AM'
,
text
:
'First added model'
,
quote
:
'Should be listed third'
}
]
},
getView
,
tabInfo
,
recentActivityTabId
;
getView
=
function
(
collection
,
tabsCollection
,
options
)
{
getView
=
function
(
collection
,
tabsCollection
,
options
)
{
var
view
;
var
view
;
...
@@ -35,6 +43,7 @@ define([
...
@@ -35,6 +43,7 @@ define([
el
:
$
(
'.wrapper-student-notes'
),
el
:
$
(
'.wrapper-student-notes'
),
collection
:
collection
,
collection
:
collection
,
tabsCollection
:
tabsCollection
,
tabsCollection
:
tabsCollection
,
createHeaderFooter
:
true
});
});
view
=
new
RecentActivityView
(
options
);
view
=
new
RecentActivityView
(
options
);
...
@@ -43,6 +52,17 @@ define([
...
@@ -43,6 +52,17 @@ define([
return
view
;
return
view
;
};
};
tabInfo
=
{
name
:
'Recent Activity'
,
identifier
:
'view-recent-activity'
,
icon
:
'fa fa-clock-o'
,
is_active
:
true
,
is_closable
:
false
,
view
:
'Recent Activity'
};
recentActivityTabId
=
'#recent-panel'
;
beforeEach
(
function
()
{
beforeEach
(
function
()
{
customMatchers
(
this
);
customMatchers
(
this
);
loadFixtures
(
'js/fixtures/edxnotes/edxnotes.html'
);
loadFixtures
(
'js/fixtures/edxnotes/edxnotes.html'
);
...
@@ -50,28 +70,135 @@ define([
...
@@ -50,28 +70,135 @@ define([
'templates/edxnotes/note-item'
,
'templates/edxnotes/tab-item'
'templates/edxnotes/note-item'
,
'templates/edxnotes/tab-item'
]);
]);
this
.
collection
=
new
NotesCollection
(
notes
);
this
.
collection
=
new
NotesCollection
(
notes
,
{
perPage
:
10
,
parse
:
true
}
);
this
.
tabsCollection
=
new
TabsCollection
();
this
.
tabsCollection
=
new
TabsCollection
();
});
});
it
(
'displays a tab and content with proper data and order'
,
function
()
{
it
(
'displays a tab and content with proper data and order'
,
function
()
{
var
view
=
getView
(
this
.
collection
,
this
.
tabsCollection
);
var
view
=
getView
(
this
.
collection
,
this
.
tabsCollection
);
Helpers
.
verifyPaginationInfo
(
view
,
"Showing 1-3 out of 3 total"
,
1
,
1
);
Helpers
.
verifyPageData
(
view
,
this
.
tabsCollection
,
tabInfo
,
recentActivityTabId
,
notes
);
});
expect
(
this
.
tabsCollection
).
toHaveLength
(
1
);
it
(
"will not render header and footer if there are no notes"
,
function
()
{
expect
(
this
.
tabsCollection
.
at
(
0
).
toJSON
()).
toEqual
({
var
notes
=
{
name
:
'Recent Activity'
,
'count'
:
0
,
identifier
:
'view-recent-activity'
,
'current_page'
:
1
,
icon
:
'fa fa-clock-o'
,
'num_pages'
:
1
,
is_active
:
true
,
'start'
:
0
,
is_closable
:
false
,
'next'
:
null
,
view
:
'Recent Activity'
'previous'
:
null
,
});
'results'
:
[]
expect
(
view
.
$
(
'#recent-panel'
)).
toExist
();
};
expect
(
view
.
$
(
'.note'
)).
toHaveLength
(
3
);
var
collection
=
new
NotesCollection
(
notes
,
{
perPage
:
10
,
parse
:
true
});
_
.
each
(
view
.
$
(
'.note'
),
function
(
element
,
index
)
{
var
view
=
getView
(
collection
,
this
.
tabsCollection
);
expect
(
$
(
'.note-comments'
,
element
)).
toContainText
(
notes
[
index
].
text
);
expect
(
view
.
$
(
'.search-tools.listing-tools'
)).
toHaveLength
(
0
);
expect
(
$
(
'.note-excerpt'
,
element
)).
toContainText
(
notes
[
index
].
quote
);
expect
(
view
.
$
(
'.pagination.pagination-full.bottom'
)).
toHaveLength
(
0
);
});
});
it
(
"can go to a page number"
,
function
()
{
var
requests
=
AjaxHelpers
.
requests
(
this
);
var
notes
=
Helpers
.
createNotesData
(
{
numNotesToCreate
:
10
,
count
:
12
,
num_pages
:
2
,
current_page
:
1
,
start
:
0
}
);
var
collection
=
new
NotesCollection
(
notes
,
{
perPage
:
10
,
parse
:
true
});
var
view
=
getView
(
collection
,
this
.
tabsCollection
);
Helpers
.
verifyPaginationInfo
(
view
,
"Showing 1-10 out of 12 total"
,
1
,
2
);
Helpers
.
verifyPageData
(
view
,
this
.
tabsCollection
,
tabInfo
,
recentActivityTabId
,
notes
);
view
.
$
(
'input#page-number-input'
).
val
(
'2'
);
view
.
$
(
'input#page-number-input'
).
trigger
(
'change'
);
Helpers
.
verifyRequestParams
(
requests
[
requests
.
length
-
1
].
url
,
{
page
:
'2'
,
page_size
:
'10'
}
);
notes
=
Helpers
.
createNotesData
(
{
numNotesToCreate
:
2
,
count
:
12
,
num_pages
:
2
,
current_page
:
2
,
start
:
10
}
);
Helpers
.
respondToRequest
(
requests
,
notes
,
true
);
Helpers
.
verifyPaginationInfo
(
view
,
"Showing 11-12 out of 12 total"
,
2
,
2
);
Helpers
.
verifyPageData
(
view
,
this
.
tabsCollection
,
tabInfo
,
recentActivityTabId
,
notes
);
});
it
(
"can navigate forward and backward"
,
function
()
{
var
requests
=
AjaxHelpers
.
requests
(
this
);
var
page1Notes
=
Helpers
.
createNotesData
(
{
numNotesToCreate
:
10
,
count
:
15
,
num_pages
:
2
,
current_page
:
1
,
start
:
0
}
);
var
collection
=
new
NotesCollection
(
page1Notes
,
{
perPage
:
10
,
parse
:
true
});
var
view
=
getView
(
collection
,
this
.
tabsCollection
);
Helpers
.
verifyPaginationInfo
(
view
,
"Showing 1-10 out of 15 total"
,
1
,
2
);
Helpers
.
verifyPageData
(
view
,
this
.
tabsCollection
,
tabInfo
,
recentActivityTabId
,
page1Notes
);
view
.
$
(
'.pagination .next-page-link'
).
click
();
Helpers
.
verifyRequestParams
(
requests
[
requests
.
length
-
1
].
url
,
{
page
:
'2'
,
page_size
:
'10'
}
);
var
page2Notes
=
Helpers
.
createNotesData
(
{
numNotesToCreate
:
5
,
count
:
15
,
num_pages
:
2
,
current_page
:
2
,
start
:
10
}
);
Helpers
.
respondToRequest
(
requests
,
page2Notes
,
true
);
Helpers
.
verifyPaginationInfo
(
view
,
"Showing 11-15 out of 15 total"
,
2
,
2
);
Helpers
.
verifyPageData
(
view
,
this
.
tabsCollection
,
tabInfo
,
recentActivityTabId
,
page2Notes
);
view
.
$
(
'.pagination .previous-page-link'
).
click
();
Helpers
.
verifyRequestParams
(
requests
[
requests
.
length
-
1
].
url
,
{
page
:
'1'
,
page_size
:
'10'
}
);
Helpers
.
respondToRequest
(
requests
,
page1Notes
);
Helpers
.
verifyPaginationInfo
(
view
,
"Showing 1-10 out of 15 total"
,
1
,
2
);
Helpers
.
verifyPageData
(
view
,
this
.
tabsCollection
,
tabInfo
,
recentActivityTabId
,
page1Notes
);
});
it
(
"sends correct page size value"
,
function
()
{
var
requests
=
AjaxHelpers
.
requests
(
this
);
var
notes
=
Helpers
.
createNotesData
(
{
numNotesToCreate
:
5
,
count
:
7
,
num_pages
:
2
,
current_page
:
1
,
start
:
0
}
);
var
collection
=
new
NotesCollection
(
notes
,
{
perPage
:
5
,
parse
:
true
});
var
view
=
getView
(
collection
,
this
.
tabsCollection
);
view
.
$
(
'.pagination .next-page-link'
).
click
();
Helpers
.
verifyRequestParams
(
requests
[
requests
.
length
-
1
].
url
,
{
page
:
'2'
,
page_size
:
'5'
}
);
});
});
});
});
});
});
lms/static/js/spec/edxnotes/views/tabs/search_results_spec.js
View file @
13b14e0a
This diff is collapsed.
Click to expand it.
lms/static/js/spec/edxnotes/views/tabs/tags_spec.js
View file @
13b14e0a
...
@@ -44,7 +44,7 @@ define([
...
@@ -44,7 +44,7 @@ define([
'templates/edxnotes/note-item'
,
'templates/edxnotes/tab-item'
'templates/edxnotes/note-item'
,
'templates/edxnotes/tab-item'
]);
]);
this
.
collection
=
new
NotesCollection
(
notes
);
this
.
collection
=
new
NotesCollection
(
notes
,
{
perPage
:
10
,
parse
:
true
}
);
this
.
tabsCollection
=
new
TabsCollection
();
this
.
tabsCollection
=
new
TabsCollection
();
});
});
...
...
lms/static/sass/course/_student-notes.scss
View file @
13b14e0a
...
@@ -235,27 +235,24 @@ $divider-visual-tertiary: ($baseline/20) solid $gray-l4;
...
@@ -235,27 +235,24 @@ $divider-visual-tertiary: ($baseline/20) solid $gray-l4;
// CASE: tag matches a search query
// CASE: tag matches a search query
.reference-meta.reference-tags
.note-highlight
{
.reference-meta.reference-tags
.note-highlight
{
// needed because .note-highlight is a span, which overrides the color
@extend
%shame-link-text
;
background-color
:
$result-highlight-color-base
;
background-color
:
$result-highlight-color-base
;
}
}
// Put commas between tags.
// Put commas between tags.
a
.reference-meta.reference-tags
:after
{
span
.reference-meta.reference-tags
:after
{
content
:
","
;
content
:
","
;
color
:
$m-gray-d2
;
color
:
$m-gray-d2
;
}
}
// But not after the last tag.
// But not after the last tag.
a
.reference-meta.reference-tags
:last-child:after
{
span
.reference-meta.reference-tags
:last-child:after
{
content
:
""
;
content
:
""
;
}
}
// needed for poor base LMS styling scope
// needed for poor base LMS styling scope
a
.reference-meta
{
a
.reference-meta
{
@extend
%shame-link-text
;
@extend
%shame-link-text
;
}
}
}
}
}
}
...
@@ -285,6 +282,15 @@ $divider-visual-tertiary: ($baseline/20) solid $gray-l4;
...
@@ -285,6 +282,15 @@ $divider-visual-tertiary: ($baseline/20) solid $gray-l4;
.tab-panel
,
.inline-error
,
.ui-loading
{
.tab-panel
,
.inline-error
,
.ui-loading
{
@extend
%no-outline
;
@extend
%no-outline
;
border-top
:
$divider-visual-primary
;
.listing-tools
{
@include
margin
(
$baseline
$baseline
(
-
$baseline
/
2
)
0
);
}
.note-group
:first-of-type
{
border-top
:
none
;
}
}
}
.tab-panel.note-group
{
.tab-panel.note-group
{
...
...
lms/templates/edxnotes/edxnotes.html
View file @
13b14e0a
...
@@ -12,6 +12,10 @@ import json
...
@@ -12,6 +12,10 @@ import json
</
%
block>
</
%
block>
<
%
include
file=
"/courseware/course_navigation.html"
args=
"active_page='edxnotes'"
/>
<
%
include
file=
"/courseware/course_navigation.html"
args=
"active_page='edxnotes'"
/>
<
%
_notes =
json.loads(notes)
has_notes =
_notes
and
_notes
.
get
('
results
')
%
>
<section
class=
"container"
>
<section
class=
"container"
>
<div
class=
"wrapper-student-notes"
>
<div
class=
"wrapper-student-notes"
>
<div
class=
"student-notes"
>
<div
class=
"student-notes"
>
...
@@ -24,7 +28,7 @@ import json
...
@@ -24,7 +28,7 @@ import json
</h1>
</h1>
</div>
</div>
% if notes:
% if
has_
notes:
<div
class=
"wrapper-notes-search"
>
<div
class=
"wrapper-notes-search"
>
<form
role=
"search"
action=
"${notes_endpoint}"
method=
"GET"
id=
"search-notes-form"
class=
"is-hidden"
>
<form
role=
"search"
action=
"${notes_endpoint}"
method=
"GET"
id=
"search-notes-form"
class=
"is-hidden"
>
<label
for=
"search-notes-input"
class=
"sr"
>
${_('Search notes for:')}
</label>
<label
for=
"search-notes-input"
class=
"sr"
>
${_('Search notes for:')}
</label>
...
@@ -51,7 +55,7 @@ import json
...
@@ -51,7 +55,7 @@ import json
<h2
id=
"tab-view"
class=
"tabs-label"
>
${_('View notes by:')}
</h2>
<h2
id=
"tab-view"
class=
"tabs-label"
>
${_('View notes by:')}
</h2>
</div>
</div>
% if notes:
% if
has_
notes:
<div
class=
"ui-loading"
tabindex=
"-1"
>
<div
class=
"ui-loading"
tabindex=
"-1"
>
<span
class=
"spin"
>
<span
class=
"spin"
>
<i
class=
"icon fa fa-refresh"
></i>
<i
class=
"icon fa fa-refresh"
></i>
...
@@ -103,11 +107,14 @@ import json
...
@@ -103,11 +107,14 @@ import json
% endfor
% endfor
</
%
block>
</
%
block>
% if notes:
% if
has_
notes:
<
%
block
name=
"js_extra"
>
<
%
block
name=
"js_extra"
>
<
%
static:require_module
module_name=
"js/edxnotes/views/page_factory"
class_name=
"NotesPageFactory"
>
<
%
static:require_module
module_name=
"js/edxnotes/views/page_factory"
class_name=
"NotesPageFactory"
>
NotesPageFactory({
NotesPageFactory({
notesList: ${notes if notes is not None else []},
disabledTabs: ${disabled_tabs},
notes: ${notes},
notesEndpoint: '${notes_endpoint}',
pageSize: '${page_size}',
debugMode: ${debug}
debugMode: ${debug}
});
});
</
%
static:require
_module
>
</
%
static:require
_module
>
...
...
lms/templates/edxnotes/note-item.underscore
View file @
13b14e0a
...
@@ -38,7 +38,7 @@
...
@@ -38,7 +38,7 @@
<% if (tags.length > 0) { %>
<% if (tags.length > 0) { %>
<p class="reference-title"><%- gettext("Tags:") %></p>
<p class="reference-title"><%- gettext("Tags:") %></p>
<% for (var i = 0; i < tags.length; i++) { %>
<% for (var i = 0; i < tags.length; i++) { %>
<
a class="reference-meta reference-tags" href="#"><%= tags[i] %></a
>
<
span class="reference-meta reference-tags"><%= tags[i] %></span
>
<% } %>
<% } %>
<% } %>
<% } %>
</div>
</div>
...
...
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