fix: migrate remaining eslint-config-edx (#31760)

* fix: migrate remaining eslint-config-edx

* refactor: updated eslint rules according to eslint-config-edx-es5

* refactor: add custom rules to suppress unnecessary eslint issues

* refactor: add custom rules to internal eslint configs

* fix: fix all indentation issues

* chore: update lock file
This commit is contained in:
Syed Ali Abbas Zaidi
2023-03-02 16:16:50 +05:00
committed by GitHub
parent 9cdbe72b82
commit 5549db4d80
495 changed files with 74392 additions and 44320 deletions

View File

@@ -6,136 +6,136 @@ import $ from 'jquery';
class AnnouncementSkipLink extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
$.get('/announcements/page/1')
.then(data => {
this.setState({
count: data.count
});
})
}
constructor(props) {
super(props);
this.state = {
count: 0
};
$.get('/announcements/page/1')
.then(data => {
this.setState({
count: data.count
});
})
}
render() {
return (<div>{"Skip to list of " + this.state.count + " announcements"}</div>)
}
render() {
return (<div>{"Skip to list of " + this.state.count + " announcements"}</div>)
}
}
class Announcement extends React.Component {
render() {
return (
<div
className="announcement"
dangerouslySetInnerHTML={{__html: this.props.content}}
>
</div>
);
}
render() {
return (
<div
className="announcement"
dangerouslySetInnerHTML={{__html: this.props.content}}
>
</div>
);
}
}
Announcement.propTypes = {
content: PropTypes.string.isRequired,
content: PropTypes.string.isRequired,
};
class AnnouncementList extends React.Component {
constructor(props) {
super(props);
this.state = {
page: 1,
announcements: [],
num_pages: 0,
has_prev: false,
has_next: false,
start_index: 0,
end_index: 0,
};
}
retrievePage(page) {
$.get('/announcements/page/' + page)
.then(data => {
this.setState({
announcements: data.announcements,
has_next: data.next,
has_prev: data.prev,
num_pages: data.num_pages,
count: data.count,
start_index: data.start_index,
end_index: data.end_index,
page: page
});
})
}
renderPrevPage() {
this.retrievePage(this.state.page - 1);
}
renderNextPage() {
this.retrievePage(this.state.page + 1);
}
componentWillMount() {
this.retrievePage(this.state.page);
}
render() {
var children = this.state.announcements.map(
(announcement, index) => <Announcement key={index} content={announcement.content} />
);
if (this.state.has_prev)
{
var prev_button = (
<div>
<Button
className={["announcement-button", "prev"]}
onClick={() => this.renderPrevPage()}
label="← previous"
/>
<span className="sr-only">{this.state.start_index + " - " + this.state.end_index + ") of " + this.state.count}</span>
</div>
);
constructor(props) {
super(props);
this.state = {
page: 1,
announcements: [],
num_pages: 0,
has_prev: false,
has_next: false,
start_index: 0,
end_index: 0,
};
}
if (this.state.has_next)
{
var next_button = (
<div>
<Button
className={["announcement-button", "next"]}
onClick={() => this.renderNextPage()}
label="next →"
/>
<span className="sr-only">{this.state.start_index + " - " + this.state.end_index + ") of " + this.state.count}</span>
</div>
);
retrievePage(page) {
$.get('/announcements/page/' + page)
.then(data => {
this.setState({
announcements: data.announcements,
has_next: data.next,
has_prev: data.prev,
num_pages: data.num_pages,
count: data.count,
start_index: data.start_index,
end_index: data.end_index,
page: page
});
})
}
renderPrevPage() {
this.retrievePage(this.state.page - 1);
}
renderNextPage() {
this.retrievePage(this.state.page + 1);
}
componentWillMount() {
this.retrievePage(this.state.page);
}
render() {
var children = this.state.announcements.map(
(announcement, index) => <Announcement key={index} content={announcement.content} />
);
if (this.state.has_prev)
{
var prev_button = (
<div>
<Button
className={["announcement-button", "prev"]}
onClick={() => this.renderPrevPage()}
label="← previous"
/>
<span className="sr-only">{this.state.start_index + " - " + this.state.end_index + ") of " + this.state.count}</span>
</div>
);
}
if (this.state.has_next)
{
var next_button = (
<div>
<Button
className={["announcement-button", "next"]}
onClick={() => this.renderNextPage()}
label="next →"
/>
<span className="sr-only">{this.state.start_index + " - " + this.state.end_index + ") of " + this.state.count}</span>
</div>
);
}
return (
<div className="announcements-list">
{children}
{prev_button}
{next_button}
</div>
);
}
return (
<div className="announcements-list">
{children}
{prev_button}
{next_button}
</div>
);
}
}
export default class AnnouncementsView {
constructor() {
ReactDOM.render(
<AnnouncementList />,
document.getElementById('announcements'),
);
ReactDOM.render(
<AnnouncementSkipLink />,
document.getElementById('announcements-skip'),
);
}
constructor() {
ReactDOM.render(
<AnnouncementList />,
document.getElementById('announcements'),
);
ReactDOM.render(
<AnnouncementSkipLink />,
document.getElementById('announcements-skip'),
);
}
}
export { AnnouncementsView, AnnouncementList, AnnouncementSkipLink }

View File

@@ -5,22 +5,22 @@ import testAnnouncements from "./test-announcements.json"
import { AnnouncementSkipLink, AnnouncementList } from "./Announcements"
describe('Announcements component', () => {
test('render skip link', () => {
const component = renderer.create(
<AnnouncementSkipLink />,
);
component.root.instance.setState({"count": 10})
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
test('render skip link', () => {
const component = renderer.create(
<AnnouncementSkipLink />,
);
component.root.instance.setState({"count": 10})
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
test('render test announcements', () => {
const component = renderer.create(
<AnnouncementList />,
);
component.root.instance.setState(testAnnouncements);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
test('render test announcements', () => {
const component = renderer.create(
<AnnouncementList />,
);
component.root.instance.setState(testAnnouncements);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
});

View File

@@ -2,162 +2,162 @@ define([
'backbone', 'jquery', 'underscore', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers',
'common/js/spec_helpers/template_helpers', 'course_bookmarks/js/views/bookmark_button'
],
function(Backbone, $, _, AjaxHelpers, TemplateHelpers, BookmarkButtonView) {
'use strict';
function(Backbone, $, _, AjaxHelpers, TemplateHelpers, BookmarkButtonView) {
'use strict';
describe('BookmarkButtonView', function() {
var createBookmarkButtonView, verifyBookmarkButtonState;
describe('BookmarkButtonView', function() {
var createBookmarkButtonView, verifyBookmarkButtonState;
var API_URL = 'bookmarks/api/v1/bookmarks/';
var API_URL = 'bookmarks/api/v1/bookmarks/';
beforeEach(function() {
loadFixtures('course_bookmarks/fixtures/bookmark_button.html');
TemplateHelpers.installTemplates(
[
'templates/fields/message_banner'
]
beforeEach(function() {
loadFixtures('course_bookmarks/fixtures/bookmark_button.html');
TemplateHelpers.installTemplates(
[
'templates/fields/message_banner'
]
);
jasmine.createSpy('timerCallback');
jasmine.clock().install();
});
afterEach(function() {
jasmine.clock().uninstall();
});
createBookmarkButtonView = function(isBookmarked) {
return new BookmarkButtonView({
el: '.bookmark-button',
bookmarked: isBookmarked,
bookmarkId: 'bilbo,usage_1',
usageId: 'usage_1',
apiUrl: API_URL
});
};
verifyBookmarkButtonState = function(view, bookmarked) {
if (bookmarked) {
expect(view.$el).toHaveAttr('aria-pressed', 'true');
expect(view.$el).toHaveClass('bookmarked');
} else {
expect(view.$el).toHaveAttr('aria-pressed', 'false');
expect(view.$el).not.toHaveClass('bookmarked');
}
expect(view.$el.data('bookmarkId')).toBe('bilbo,usage_1');
};
it('rendered correctly', function() {
var view = createBookmarkButtonView(false);
verifyBookmarkButtonState(view, false);
// with bookmarked true
view = createBookmarkButtonView(true);
verifyBookmarkButtonState(view, true);
});
it('bookmark/un-bookmark the block correctly', function() {
var addBookmarkedData = {
bookmarked: true,
handler: 'removeBookmark',
event: 'bookmark:remove',
method: 'DELETE',
url: API_URL + 'bilbo,usage_1/',
body: null
};
var removeBookmarkData = {
bookmarked: false,
handler: 'addBookmark',
event: 'bookmark:add',
method: 'POST',
url: API_URL,
body: 'usage_id=usage_1'
};
var requests = AjaxHelpers.requests(this);
var bookmarkedData = [[addBookmarkedData, removeBookmarkData], [removeBookmarkData, addBookmarkedData]];
_.each(bookmarkedData, function(actionsData) {
var firstActionData = actionsData[0];
var secondActionData = actionsData[1];
var bookmarkButtonView = createBookmarkButtonView(firstActionData.bookmarked);
verifyBookmarkButtonState(bookmarkButtonView, firstActionData.bookmarked);
spyOn(bookmarkButtonView, firstActionData.handler).and.callThrough();
spyOnEvent(bookmarkButtonView.$el, firstActionData.event);
bookmarkButtonView.$el.click();
expect(bookmarkButtonView.$el).toHaveAttr('disabled', 'disabled');
AjaxHelpers.expectRequest(
requests, firstActionData.method,
firstActionData.url,
firstActionData.body
);
jasmine.createSpy('timerCallback');
jasmine.clock().install();
});
expect(bookmarkButtonView[firstActionData.handler]).toHaveBeenCalled();
AjaxHelpers.respondWithJson(requests, {});
expect(firstActionData.event).toHaveBeenTriggeredOn(bookmarkButtonView.$el);
bookmarkButtonView[firstActionData.handler].calls.reset();
afterEach(function() {
jasmine.clock().uninstall();
});
expect(bookmarkButtonView.$el).not.toHaveAttr('disabled');
verifyBookmarkButtonState(bookmarkButtonView, secondActionData.bookmarked);
createBookmarkButtonView = function(isBookmarked) {
return new BookmarkButtonView({
el: '.bookmark-button',
bookmarked: isBookmarked,
bookmarkId: 'bilbo,usage_1',
usageId: 'usage_1',
apiUrl: API_URL
});
};
spyOn(bookmarkButtonView, secondActionData.handler).and.callThrough();
spyOnEvent(bookmarkButtonView.$el, secondActionData.event);
verifyBookmarkButtonState = function(view, bookmarked) {
if (bookmarked) {
expect(view.$el).toHaveAttr('aria-pressed', 'true');
expect(view.$el).toHaveClass('bookmarked');
} else {
expect(view.$el).toHaveAttr('aria-pressed', 'false');
expect(view.$el).not.toHaveClass('bookmarked');
}
expect(view.$el.data('bookmarkId')).toBe('bilbo,usage_1');
};
it('rendered correctly', function() {
var view = createBookmarkButtonView(false);
verifyBookmarkButtonState(view, false);
// with bookmarked true
view = createBookmarkButtonView(true);
verifyBookmarkButtonState(view, true);
});
it('bookmark/un-bookmark the block correctly', function() {
var addBookmarkedData = {
bookmarked: true,
handler: 'removeBookmark',
event: 'bookmark:remove',
method: 'DELETE',
url: API_URL + 'bilbo,usage_1/',
body: null
};
var removeBookmarkData = {
bookmarked: false,
handler: 'addBookmark',
event: 'bookmark:add',
method: 'POST',
url: API_URL,
body: 'usage_id=usage_1'
};
var requests = AjaxHelpers.requests(this);
var bookmarkedData = [[addBookmarkedData, removeBookmarkData], [removeBookmarkData, addBookmarkedData]];
_.each(bookmarkedData, function(actionsData) {
var firstActionData = actionsData[0];
var secondActionData = actionsData[1];
var bookmarkButtonView = createBookmarkButtonView(firstActionData.bookmarked);
verifyBookmarkButtonState(bookmarkButtonView, firstActionData.bookmarked);
spyOn(bookmarkButtonView, firstActionData.handler).and.callThrough();
spyOnEvent(bookmarkButtonView.$el, firstActionData.event);
bookmarkButtonView.$el.click();
expect(bookmarkButtonView.$el).toHaveAttr('disabled', 'disabled');
AjaxHelpers.expectRequest(
requests, firstActionData.method,
firstActionData.url,
firstActionData.body
);
expect(bookmarkButtonView[firstActionData.handler]).toHaveBeenCalled();
AjaxHelpers.respondWithJson(requests, {});
expect(firstActionData.event).toHaveBeenTriggeredOn(bookmarkButtonView.$el);
bookmarkButtonView[firstActionData.handler].calls.reset();
expect(bookmarkButtonView.$el).not.toHaveAttr('disabled');
verifyBookmarkButtonState(bookmarkButtonView, secondActionData.bookmarked);
spyOn(bookmarkButtonView, secondActionData.handler).and.callThrough();
spyOnEvent(bookmarkButtonView.$el, secondActionData.event);
bookmarkButtonView.$el.click();
expect(bookmarkButtonView.$el).toHaveAttr('disabled', 'disabled');
AjaxHelpers.expectRequest(
requests,
secondActionData.method,
secondActionData.url,
secondActionData.body
);
expect(bookmarkButtonView[secondActionData.handler]).toHaveBeenCalled();
AjaxHelpers.respondWithJson(requests, {});
expect(secondActionData.event).toHaveBeenTriggeredOn(bookmarkButtonView.$el);
expect(bookmarkButtonView.$el).not.toHaveAttr('disabled');
verifyBookmarkButtonState(bookmarkButtonView, firstActionData.bookmarked);
bookmarkButtonView.undelegateEvents();
});
});
it('shows an error message for HTTP 500', function() {
var requests = AjaxHelpers.requests(this),
$messageBanner = $('.message-banner'),
bookmarkButtonView = createBookmarkButtonView(false);
bookmarkButtonView.$el.click();
expect(bookmarkButtonView.$el).toHaveAttr('disabled', 'disabled');
AjaxHelpers.respondWithError(requests);
AjaxHelpers.expectRequest(
requests,
secondActionData.method,
secondActionData.url,
secondActionData.body
);
expect($messageBanner.text().trim()).toBe(bookmarkButtonView.errorMessage);
expect(bookmarkButtonView[secondActionData.handler]).toHaveBeenCalled();
AjaxHelpers.respondWithJson(requests, {});
expect(secondActionData.event).toHaveBeenTriggeredOn(bookmarkButtonView.$el);
// For bookmarked button.
bookmarkButtonView = createBookmarkButtonView(true);
bookmarkButtonView.$el.click();
AjaxHelpers.respondWithError(requests);
expect($messageBanner.text().trim()).toBe(bookmarkButtonView.errorMessage);
});
it('removes error message after 5 seconds', function() {
var requests = AjaxHelpers.requests(this),
$messageBanner = $('.message-banner'),
bookmarkButtonView = createBookmarkButtonView(false);
bookmarkButtonView.$el.click();
AjaxHelpers.respondWithError(requests);
expect($messageBanner.text().trim()).toBe(bookmarkButtonView.errorMessage);
jasmine.clock().tick(5001);
expect($messageBanner.text().trim()).toBe('');
expect(bookmarkButtonView.$el).not.toHaveAttr('disabled');
verifyBookmarkButtonState(bookmarkButtonView, firstActionData.bookmarked);
bookmarkButtonView.undelegateEvents();
});
});
it('shows an error message for HTTP 500', function() {
var requests = AjaxHelpers.requests(this),
$messageBanner = $('.message-banner'),
bookmarkButtonView = createBookmarkButtonView(false);
bookmarkButtonView.$el.click();
AjaxHelpers.respondWithError(requests);
expect($messageBanner.text().trim()).toBe(bookmarkButtonView.errorMessage);
// For bookmarked button.
bookmarkButtonView = createBookmarkButtonView(true);
bookmarkButtonView.$el.click();
AjaxHelpers.respondWithError(requests);
expect($messageBanner.text().trim()).toBe(bookmarkButtonView.errorMessage);
});
it('removes error message after 5 seconds', function() {
var requests = AjaxHelpers.requests(this),
$messageBanner = $('.message-banner'),
bookmarkButtonView = createBookmarkButtonView(false);
bookmarkButtonView.$el.click();
AjaxHelpers.respondWithError(requests);
expect($messageBanner.text().trim()).toBe(bookmarkButtonView.errorMessage);
jasmine.clock().tick(5001);
expect($messageBanner.text().trim()).toBe('');
});
});
});

View File

@@ -11,252 +11,252 @@ define([
'course_bookmarks/js/views/bookmarks_list',
'course_bookmarks/js/collections/bookmarks'
],
function(Backbone, $, _, Logger, URI, AjaxHelpers, TemplateHelpers, MessageBannerView,
BookmarkHelpers, BookmarksListView, BookmarksCollection) {
'use strict';
function(Backbone, $, _, Logger, URI, AjaxHelpers, TemplateHelpers, MessageBannerView,
BookmarkHelpers, BookmarksListView, BookmarksCollection) {
'use strict';
describe('BookmarksListView', function() {
var createBookmarksView, verifyRequestParams;
describe('BookmarksListView', function() {
var createBookmarksView, verifyRequestParams;
beforeEach(function() {
loadFixtures('course_bookmarks/fixtures/bookmarks.html');
TemplateHelpers.installTemplates([
'templates/fields/message_banner'
]);
spyOn(Logger, 'log').and.returnValue($.Deferred().resolve());
jasmine.addMatchers({
toHaveBeenCalledWithUrl: function() {
return {
compare: function(actual, expectedUrl) {
return {
pass: expectedUrl === actual.calls.mostRecent().args[0].currentTarget.pathname
};
}
};
}
});
});
createBookmarksView = function() {
var bookmarksCollection = new BookmarksCollection(
[],
{
course_id: BookmarkHelpers.TEST_COURSE_ID,
url: BookmarkHelpers.TEST_API_URL
}
);
var bookmarksView = new BookmarksListView({
$el: $('.course-bookmarks'),
collection: bookmarksCollection,
loadingMessageView: new MessageBannerView({el: $('#loading-message')}),
errorMessageView: new MessageBannerView({el: $('#error-message')})
});
return bookmarksView;
};
verifyRequestParams = function(requests, params) {
var urlParams = (new URI(requests[requests.length - 1].url)).query(true);
_.each(params, function(value, key) {
expect(urlParams[key]).toBe(value);
});
};
it('can correctly render an empty bookmarks list', function() {
var requests = AjaxHelpers.requests(this);
var bookmarksView = createBookmarksView();
var expectedData = BookmarkHelpers.createBookmarksData({numBookmarksToCreate: 0});
bookmarksView.showBookmarks();
AjaxHelpers.respondWithJson(requests, expectedData);
expect(bookmarksView.$('.bookmarks-empty-header').text().trim()).toBe(
'You have not bookmarked any courseware pages yet'
);
expect(bookmarksView.$('.bookmarks-empty-detail-title').text().trim()).toBe(
'Use bookmarks to help you easily return to courseware pages. ' +
'To bookmark a page, click "Bookmark this page" under the page title.'
);
expect(bookmarksView.$('.paging-header').length).toBe(0);
expect(bookmarksView.$('.paging-footer').length).toBe(0);
});
it('has rendered bookmarked list correctly', function() {
var requests = AjaxHelpers.requests(this);
var bookmarksView = createBookmarksView();
var expectedData = BookmarkHelpers.createBookmarksData({numBookmarksToCreate: 3});
bookmarksView.showBookmarks();
verifyRequestParams(
requests,
{
course_id: BookmarkHelpers.TEST_COURSE_ID,
fields: 'display_name,path',
page: '1',
page_size: '10'
}
);
AjaxHelpers.respondWithJson(requests, expectedData);
BookmarkHelpers.verifyBookmarkedData(bookmarksView, expectedData);
expect(bookmarksView.$('.paging-header').length).toBe(1);
expect(bookmarksView.$('.paging-footer').length).toBe(1);
});
it('calls bookmarks list render on page_changed event', function() {
var renderSpy = spyOn(BookmarksListView.prototype, 'render');
var listView = new BookmarksListView({
collection: new BookmarksCollection([], {
course_id: 'abc',
url: '/test-bookmarks/url/'
})
});
listView.collection.trigger('page_changed');
expect(renderSpy).toHaveBeenCalled();
});
it('can go to a page number', function() {
var requests = AjaxHelpers.requests(this);
var expectedData = BookmarkHelpers.createBookmarksData(
{
numBookmarksToCreate: 10,
count: 12,
num_pages: 2,
current_page: 1,
start: 0
}
);
var bookmarksView = createBookmarksView();
bookmarksView.showBookmarks();
AjaxHelpers.respondWithJson(requests, expectedData);
BookmarkHelpers.verifyBookmarkedData(bookmarksView, expectedData);
bookmarksView.$('input#page-number-input').val('2');
bookmarksView.$('input#page-number-input').trigger('change');
expectedData = BookmarkHelpers.createBookmarksData(
{
numBookmarksToCreate: 2,
count: 12,
num_pages: 2,
current_page: 2,
start: 10
}
);
AjaxHelpers.respondWithJson(requests, expectedData);
BookmarkHelpers.verifyBookmarkedData(bookmarksView, expectedData);
expect(bookmarksView.$('.paging-footer span.current-page').text().trim()).toBe('2');
expect(bookmarksView.$('.paging-header span').text().trim()).toBe('Showing 11-12 out of 12 total');
});
it('can navigate forward and backward', function() {
var requests = AjaxHelpers.requests(this);
var bookmarksView = createBookmarksView();
var expectedData = BookmarkHelpers.createBookmarksData(
{
numBookmarksToCreate: 10,
count: 15,
num_pages: 2,
current_page: 1,
start: 0
}
);
bookmarksView.showBookmarks();
BookmarkHelpers.verifyPaginationInfo(
requests,
bookmarksView,
expectedData,
'1',
'Showing 1-10 out of 15 total'
);
verifyRequestParams(
requests,
{
course_id: BookmarkHelpers.TEST_COURSE_ID,
fields: 'display_name,path',
page: '1',
page_size: '10'
}
);
bookmarksView.$('.paging-footer .next-page-link').click();
expectedData = BookmarkHelpers.createBookmarksData(
{
numBookmarksToCreate: 5,
count: 15,
num_pages: 2,
current_page: 2,
start: 10
}
);
BookmarkHelpers.verifyPaginationInfo(
requests,
bookmarksView,
expectedData,
'2',
'Showing 11-15 out of 15 total'
);
verifyRequestParams(
requests,
{
course_id: BookmarkHelpers.TEST_COURSE_ID,
fields: 'display_name,path',
page: '2',
page_size: '10'
}
);
expectedData = BookmarkHelpers.createBookmarksData(
{
numBookmarksToCreate: 10,
count: 15,
num_pages: 2,
current_page: 1,
start: 0
}
);
bookmarksView.$('.paging-footer .previous-page-link').click();
BookmarkHelpers.verifyPaginationInfo(
requests,
bookmarksView,
expectedData,
'1',
'Showing 1-10 out of 15 total'
);
verifyRequestParams(
requests,
{
course_id: BookmarkHelpers.TEST_COURSE_ID,
fields: 'display_name,path',
page: '1',
page_size: '10'
}
);
});
xit('can navigate to correct url', function() {
var requests = AjaxHelpers.requests(this);
var bookmarksView = createBookmarksView();
var url;
spyOn(bookmarksView, 'visitBookmark');
bookmarksView.showBookmarks();
AjaxHelpers.respondWithJson(requests, BookmarkHelpers.createBookmarksData({numBookmarksToCreate: 1}));
bookmarksView.$('.bookmarks-results-list-item').click();
url = bookmarksView.$('.bookmarks-results-list-item').attr('href');
expect(bookmarksView.visitBookmark).toHaveBeenCalledWithUrl(url);
});
it('shows an error message for HTTP 500', function() {
var requests = AjaxHelpers.requests(this);
var bookmarksView = createBookmarksView();
bookmarksView.showBookmarks();
AjaxHelpers.respondWithError(requests);
expect($('#error-message').text().trim()).toBe(bookmarksView.errorMessage);
beforeEach(function() {
loadFixtures('course_bookmarks/fixtures/bookmarks.html');
TemplateHelpers.installTemplates([
'templates/fields/message_banner'
]);
spyOn(Logger, 'log').and.returnValue($.Deferred().resolve());
jasmine.addMatchers({
toHaveBeenCalledWithUrl: function() {
return {
compare: function(actual, expectedUrl) {
return {
pass: expectedUrl === actual.calls.mostRecent().args[0].currentTarget.pathname
};
}
};
}
});
});
createBookmarksView = function() {
var bookmarksCollection = new BookmarksCollection(
[],
{
course_id: BookmarkHelpers.TEST_COURSE_ID,
url: BookmarkHelpers.TEST_API_URL
}
);
var bookmarksView = new BookmarksListView({
$el: $('.course-bookmarks'),
collection: bookmarksCollection,
loadingMessageView: new MessageBannerView({el: $('#loading-message')}),
errorMessageView: new MessageBannerView({el: $('#error-message')})
});
return bookmarksView;
};
verifyRequestParams = function(requests, params) {
var urlParams = (new URI(requests[requests.length - 1].url)).query(true);
_.each(params, function(value, key) {
expect(urlParams[key]).toBe(value);
});
};
it('can correctly render an empty bookmarks list', function() {
var requests = AjaxHelpers.requests(this);
var bookmarksView = createBookmarksView();
var expectedData = BookmarkHelpers.createBookmarksData({numBookmarksToCreate: 0});
bookmarksView.showBookmarks();
AjaxHelpers.respondWithJson(requests, expectedData);
expect(bookmarksView.$('.bookmarks-empty-header').text().trim()).toBe(
'You have not bookmarked any courseware pages yet'
);
expect(bookmarksView.$('.bookmarks-empty-detail-title').text().trim()).toBe(
'Use bookmarks to help you easily return to courseware pages. ' +
'To bookmark a page, click "Bookmark this page" under the page title.'
);
expect(bookmarksView.$('.paging-header').length).toBe(0);
expect(bookmarksView.$('.paging-footer').length).toBe(0);
});
it('has rendered bookmarked list correctly', function() {
var requests = AjaxHelpers.requests(this);
var bookmarksView = createBookmarksView();
var expectedData = BookmarkHelpers.createBookmarksData({numBookmarksToCreate: 3});
bookmarksView.showBookmarks();
verifyRequestParams(
requests,
{
course_id: BookmarkHelpers.TEST_COURSE_ID,
fields: 'display_name,path',
page: '1',
page_size: '10'
}
);
AjaxHelpers.respondWithJson(requests, expectedData);
BookmarkHelpers.verifyBookmarkedData(bookmarksView, expectedData);
expect(bookmarksView.$('.paging-header').length).toBe(1);
expect(bookmarksView.$('.paging-footer').length).toBe(1);
});
it('calls bookmarks list render on page_changed event', function() {
var renderSpy = spyOn(BookmarksListView.prototype, 'render');
var listView = new BookmarksListView({
collection: new BookmarksCollection([], {
course_id: 'abc',
url: '/test-bookmarks/url/'
})
});
listView.collection.trigger('page_changed');
expect(renderSpy).toHaveBeenCalled();
});
it('can go to a page number', function() {
var requests = AjaxHelpers.requests(this);
var expectedData = BookmarkHelpers.createBookmarksData(
{
numBookmarksToCreate: 10,
count: 12,
num_pages: 2,
current_page: 1,
start: 0
}
);
var bookmarksView = createBookmarksView();
bookmarksView.showBookmarks();
AjaxHelpers.respondWithJson(requests, expectedData);
BookmarkHelpers.verifyBookmarkedData(bookmarksView, expectedData);
bookmarksView.$('input#page-number-input').val('2');
bookmarksView.$('input#page-number-input').trigger('change');
expectedData = BookmarkHelpers.createBookmarksData(
{
numBookmarksToCreate: 2,
count: 12,
num_pages: 2,
current_page: 2,
start: 10
}
);
AjaxHelpers.respondWithJson(requests, expectedData);
BookmarkHelpers.verifyBookmarkedData(bookmarksView, expectedData);
expect(bookmarksView.$('.paging-footer span.current-page').text().trim()).toBe('2');
expect(bookmarksView.$('.paging-header span').text().trim()).toBe('Showing 11-12 out of 12 total');
});
it('can navigate forward and backward', function() {
var requests = AjaxHelpers.requests(this);
var bookmarksView = createBookmarksView();
var expectedData = BookmarkHelpers.createBookmarksData(
{
numBookmarksToCreate: 10,
count: 15,
num_pages: 2,
current_page: 1,
start: 0
}
);
bookmarksView.showBookmarks();
BookmarkHelpers.verifyPaginationInfo(
requests,
bookmarksView,
expectedData,
'1',
'Showing 1-10 out of 15 total'
);
verifyRequestParams(
requests,
{
course_id: BookmarkHelpers.TEST_COURSE_ID,
fields: 'display_name,path',
page: '1',
page_size: '10'
}
);
bookmarksView.$('.paging-footer .next-page-link').click();
expectedData = BookmarkHelpers.createBookmarksData(
{
numBookmarksToCreate: 5,
count: 15,
num_pages: 2,
current_page: 2,
start: 10
}
);
BookmarkHelpers.verifyPaginationInfo(
requests,
bookmarksView,
expectedData,
'2',
'Showing 11-15 out of 15 total'
);
verifyRequestParams(
requests,
{
course_id: BookmarkHelpers.TEST_COURSE_ID,
fields: 'display_name,path',
page: '2',
page_size: '10'
}
);
expectedData = BookmarkHelpers.createBookmarksData(
{
numBookmarksToCreate: 10,
count: 15,
num_pages: 2,
current_page: 1,
start: 0
}
);
bookmarksView.$('.paging-footer .previous-page-link').click();
BookmarkHelpers.verifyPaginationInfo(
requests,
bookmarksView,
expectedData,
'1',
'Showing 1-10 out of 15 total'
);
verifyRequestParams(
requests,
{
course_id: BookmarkHelpers.TEST_COURSE_ID,
fields: 'display_name,path',
page: '1',
page_size: '10'
}
);
});
xit('can navigate to correct url', function() {
var requests = AjaxHelpers.requests(this);
var bookmarksView = createBookmarksView();
var url;
spyOn(bookmarksView, 'visitBookmark');
bookmarksView.showBookmarks();
AjaxHelpers.respondWithJson(requests, BookmarkHelpers.createBookmarksData({numBookmarksToCreate: 1}));
bookmarksView.$('.bookmarks-results-list-item').click();
url = bookmarksView.$('.bookmarks-results-list-item').attr('href');
expect(bookmarksView.visitBookmark).toHaveBeenCalledWithUrl(url);
});
it('shows an error message for HTTP 500', function() {
var requests = AjaxHelpers.requests(this);
var bookmarksView = createBookmarksView();
bookmarksView.showBookmarks();
AjaxHelpers.respondWithError(requests);
expect($('#error-message').text().trim()).toBe(bookmarksView.errorMessage);
});
});
});

View File

@@ -4,34 +4,34 @@ define([
'course_bookmarks/js/spec_helpers/bookmark_helpers',
'course_bookmarks/js/course_bookmarks_factory'
],
function($, AjaxHelpers, BookmarkHelpers, CourseBookmarksFactory) {
'use strict';
function($, AjaxHelpers, BookmarkHelpers, CourseBookmarksFactory) {
'use strict';
describe('CourseBookmarksFactory', function() {
beforeEach(function() {
loadFixtures('course_bookmarks/fixtures/bookmarks.html');
});
describe('CourseBookmarksFactory', function() {
beforeEach(function() {
loadFixtures('course_bookmarks/fixtures/bookmarks.html');
});
it('can render the initial bookmarks', function() {
var requests = AjaxHelpers.requests(this),
expectedData = BookmarkHelpers.createBookmarksData(
{
numBookmarksToCreate: 10,
count: 15,
num_pages: 2,
current_page: 1,
start: 0
}
),
bookmarksView;
bookmarksView = CourseBookmarksFactory({
$el: $('.course-bookmarks'),
courseId: BookmarkHelpers.TEST_COURSE_ID,
bookmarksApiUrl: BookmarkHelpers.TEST_API_URL
});
BookmarkHelpers.verifyPaginationInfo(
requests, bookmarksView, expectedData, '1', 'Showing 1-10 out of 15 total'
);
it('can render the initial bookmarks', function() {
var requests = AjaxHelpers.requests(this),
expectedData = BookmarkHelpers.createBookmarksData(
{
numBookmarksToCreate: 10,
count: 15,
num_pages: 2,
current_page: 1,
start: 0
}
),
bookmarksView;
bookmarksView = CourseBookmarksFactory({
$el: $('.course-bookmarks'),
courseId: BookmarkHelpers.TEST_COURSE_ID,
bookmarksApiUrl: BookmarkHelpers.TEST_API_URL
});
BookmarkHelpers.verifyPaginationInfo(
requests, bookmarksView, expectedData, '1', 'Showing 1-10 out of 15 total'
);
});
});
});

View File

@@ -44,8 +44,8 @@ define(
var breadcrumbTrail = function(path, unitDisplayName) {
return _.pluck(path, 'display_name').
concat([unitDisplayName]).
join(' <span class="icon fa fa-caret-right" aria-hidden="true"></span><span class="sr">-</span> ');
concat([unitDisplayName]).
join(' <span class="icon fa fa-caret-right" aria-hidden="true"></span><span class="sr">-</span> ');
};
var verifyBookmarkedData = function(view, expectedData) {

View File

@@ -6,121 +6,121 @@
'common/js/components/views/paging_header', 'common/js/components/views/paging_footer',
'text!course_bookmarks/templates/bookmarks-list.underscore'
],
function(gettext, $, _, Backbone, Logger, _moment, HtmlUtils,
PagingHeaderView, PagingFooterView, bookmarksListTemplate) {
var moment = _moment || window.moment;
function(gettext, $, _, Backbone, Logger, _moment, HtmlUtils,
PagingHeaderView, PagingFooterView, bookmarksListTemplate) {
var moment = _moment || window.moment;
return Backbone.View.extend({
return Backbone.View.extend({
el: '.courseware-results',
coursewareContentEl: '#course-content',
coursewareResultsWrapperEl: '.courseware-results-wrapper',
el: '.courseware-results',
coursewareContentEl: '#course-content',
coursewareResultsWrapperEl: '.courseware-results-wrapper',
errorIcon: '<span class="fa fa-fw fa-exclamation-triangle message-error" aria-hidden="true"></span>',
loadingIcon: '<span class="fa fa-fw fa-spinner fa-pulse message-in-progress" aria-hidden="true"></span>', // eslint-disable-line max-len
errorIcon: '<span class="fa fa-fw fa-exclamation-triangle message-error" aria-hidden="true"></span>',
loadingIcon: '<span class="fa fa-fw fa-spinner fa-pulse message-in-progress" aria-hidden="true"></span>', // eslint-disable-line max-len
errorMessage: gettext('An error has occurred. Please try again.'),
loadingMessage: gettext('Loading'),
errorMessage: gettext('An error has occurred. Please try again.'),
loadingMessage: gettext('Loading'),
defaultPage: 1,
defaultPage: 1,
events: {
'click .bookmarks-results-list-item': 'visitBookmark'
},
events: {
'click .bookmarks-results-list-item': 'visitBookmark'
},
initialize: function(options) {
this.template = HtmlUtils.template(bookmarksListTemplate);
this.loadingMessageView = options.loadingMessageView;
this.errorMessageView = options.errorMessageView;
this.langCode = $(this.el).data('langCode');
this.pagingHeaderView = new PagingHeaderView({collection: this.collection});
this.pagingFooterView = new PagingFooterView({collection: this.collection});
this.listenTo(this.collection, 'page_changed', this.render);
_.bindAll(this, 'render', 'humanFriendlyDate');
},
initialize: function(options) {
this.template = HtmlUtils.template(bookmarksListTemplate);
this.loadingMessageView = options.loadingMessageView;
this.errorMessageView = options.errorMessageView;
this.langCode = $(this.el).data('langCode');
this.pagingHeaderView = new PagingHeaderView({collection: this.collection});
this.pagingFooterView = new PagingFooterView({collection: this.collection});
this.listenTo(this.collection, 'page_changed', this.render);
_.bindAll(this, 'render', 'humanFriendlyDate');
},
render: function() {
var data = {
bookmarksCollection: this.collection,
humanFriendlyDate: this.humanFriendlyDate
};
render: function() {
var data = {
bookmarksCollection: this.collection,
humanFriendlyDate: this.humanFriendlyDate
};
HtmlUtils.setHtml(this.$el, this.template(data));
this.pagingHeaderView.setElement(this.$('.paging-header')).render();
this.pagingFooterView.setElement(this.$('.paging-footer')).render();
this.delegateEvents();
return this;
},
HtmlUtils.setHtml(this.$el, this.template(data));
this.pagingHeaderView.setElement(this.$('.paging-header')).render();
this.pagingFooterView.setElement(this.$('.paging-footer')).render();
this.delegateEvents();
return this;
},
showBookmarks: function() {
var view = this;
showBookmarks: function() {
var view = this;
this.hideErrorMessage();
this.showBookmarksContainer();
this.hideErrorMessage();
this.showBookmarksContainer();
this.collection.getPage(this.defaultPage).done(function() {
view.render();
view.focusBookmarksElement();
}).fail(function() {
view.showErrorMessage();
});
},
this.collection.getPage(this.defaultPage).done(function() {
view.render();
view.focusBookmarksElement();
}).fail(function() {
view.showErrorMessage();
});
},
visitBookmark: function(event) {
var $bookmarkedComponent = $(event.currentTarget),
bookmarkId = $bookmarkedComponent.data('bookmarkId'),
componentUsageId = $bookmarkedComponent.data('usageId'),
componentType = $bookmarkedComponent.data('componentType');
Logger.log(
'edx.bookmark.accessed',
{
bookmark_id: bookmarkId,
component_type: componentType,
component_usage_id: componentUsageId
}
).always(function() {
window.location.href = event.currentTarget.pathname;
});
},
visitBookmark: function(event) {
var $bookmarkedComponent = $(event.currentTarget),
bookmarkId = $bookmarkedComponent.data('bookmarkId'),
componentUsageId = $bookmarkedComponent.data('usageId'),
componentType = $bookmarkedComponent.data('componentType');
Logger.log(
'edx.bookmark.accessed',
{
bookmark_id: bookmarkId,
component_type: componentType,
component_usage_id: componentUsageId
}
).always(function() {
window.location.href = event.currentTarget.pathname;
});
},
/**
/**
* Convert ISO 8601 formatted date into human friendly format.
*
* e.g, `2014-05-23T14:00:00Z` to `May 23, 2014`
*
* @param {String} isoDate - ISO 8601 formatted date string.
*/
humanFriendlyDate: function(isoDate) {
moment.locale(this.langCode);
return moment(isoDate).format('LL');
},
humanFriendlyDate: function(isoDate) {
moment.locale(this.langCode);
return moment(isoDate).format('LL');
},
showBookmarksContainer: function() {
$(this.coursewareContentEl).hide();
// Empty el if it's not empty to get the clean state.
this.$el.html('');
this.$el.show();
},
showBookmarksContainer: function() {
$(this.coursewareContentEl).hide();
// Empty el if it's not empty to get the clean state.
this.$el.html('');
this.$el.show();
},
showLoadingMessage: function() {
this.loadingMessageView.showMessage(this.loadingMessage, this.loadingIcon);
},
showLoadingMessage: function() {
this.loadingMessageView.showMessage(this.loadingMessage, this.loadingIcon);
},
hideLoadingMessage: function() {
this.loadingMessageView.hideMessage();
},
hideLoadingMessage: function() {
this.loadingMessageView.hideMessage();
},
showErrorMessage: function() {
this.errorMessageView.showMessage(this.errorMessage, this.errorIcon);
},
showErrorMessage: function() {
this.errorMessageView.showMessage(this.errorMessage, this.errorIcon);
},
hideErrorMessage: function() {
this.errorMessageView.hideMessage();
},
hideErrorMessage: function() {
this.errorMessageView.hideMessage();
},
focusBookmarksElement: function() {
this.$('#my-bookmarks').focus();
}
});
focusBookmarksElement: function() {
this.$('#my-bookmarks').focus();
}
});
});
}).call(this, define || RequireJS.define);

View File

@@ -1,11 +1,18 @@
module.exports = {
extends: 'eslint-config-edx',
root: true,
settings: {
'import/resolver': {
webpack: {
config: 'webpack.dev.config.js',
},
extends: '@edx/eslint-config',
root: true,
settings: {
'import/resolver': {
webpack: {
config: 'webpack.dev.config.js',
},
},
},
rules: {
indent: ['error', 4],
'import/extensions': 'off',
'import/no-unresolved': 'off',
'react/jsx-indent': 'off',
'react/jsx-indent-props': 'off',
},
},
};

View File

@@ -1,83 +1,83 @@
/* globals Logger */
export class CourseSock { // eslint-disable-line import/prefer-default-export
constructor() {
const $toggleActionButton = $('.action-toggle-verification-sock');
const $verificationSock = $('.verification-sock .verification-main-panel');
const $upgradeToVerifiedButton = $('.verification-sock .action-upgrade-certificate');
const $miniCert = $('.mini-cert');
const pageLocation = window.location.href.indexOf('courseware') > -1
? 'Course Content Page' : 'Home Page';
constructor() {
const $toggleActionButton = $('.action-toggle-verification-sock');
const $verificationSock = $('.verification-sock .verification-main-panel');
const $upgradeToVerifiedButton = $('.verification-sock .action-upgrade-certificate');
const $miniCert = $('.mini-cert');
const pageLocation = window.location.href.indexOf('courseware') > -1
? 'Course Content Page' : 'Home Page';
// Behavior to fix button to bottom of screen on scroll
const fixUpgradeButton = () => {
if (!$upgradeToVerifiedButton.is(':visible')) return;
// Behavior to fix button to bottom of screen on scroll
const fixUpgradeButton = () => {
if (!$upgradeToVerifiedButton.is(':visible')) return;
// Grab the current scroll location
const documentBottom = $(window).scrollTop() + $(window).height();
// Grab the current scroll location
const documentBottom = $(window).scrollTop() + $(window).height();
// Establish a sliding window in which the button is fixed
const startFixed = $verificationSock.offset().top + 320;
const endFixed = (startFixed + $verificationSock.height()) - 220;
// Establish a sliding window in which the button is fixed
const startFixed = $verificationSock.offset().top + 320;
const endFixed = (startFixed + $verificationSock.height()) - 220;
// Ensure update button stays in sock even when max-width is exceeded
const distRight = window.outerWidth - ($miniCert.offset().left + $miniCert.width());
// Ensure update button stays in sock even when max-width is exceeded
const distRight = window.outerWidth - ($miniCert.offset().left + $miniCert.width());
// Update positioning when scrolling is in fixed window and screen width is sufficient
if ((documentBottom > startFixed && documentBottom < endFixed
// Update positioning when scrolling is in fixed window and screen width is sufficient
if ((documentBottom > startFixed && documentBottom < endFixed
&& $(window).width() > 960)) {
$upgradeToVerifiedButton.addClass('attached');
$upgradeToVerifiedButton.css('right', `${distRight}px`);
} else {
// If outside sliding window, reset to un-attached state
$upgradeToVerifiedButton.removeClass('attached');
$upgradeToVerifiedButton.css('right', '20px');
$upgradeToVerifiedButton.addClass('attached');
$upgradeToVerifiedButton.css('right', `${distRight}px`);
} else {
// If outside sliding window, reset to un-attached state
$upgradeToVerifiedButton.removeClass('attached');
$upgradeToVerifiedButton.css('right', '20px');
// Add class to define absolute location
if (documentBottom < startFixed) {
$upgradeToVerifiedButton.addClass('stuck-top');
$upgradeToVerifiedButton.removeClass('stuck-bottom');
} else if (documentBottom > endFixed) {
$upgradeToVerifiedButton.addClass('stuck-bottom');
$upgradeToVerifiedButton.removeClass('stuck-top');
// Add class to define absolute location
if (documentBottom < startFixed) {
$upgradeToVerifiedButton.addClass('stuck-top');
$upgradeToVerifiedButton.removeClass('stuck-bottom');
} else if (documentBottom > endFixed) {
$upgradeToVerifiedButton.addClass('stuck-bottom');
$upgradeToVerifiedButton.removeClass('stuck-top');
}
}
};
// Fix the sock to the screen on scroll and resize events
if ($upgradeToVerifiedButton.length) {
$(window).scroll(fixUpgradeButton).resize(fixUpgradeButton);
}
}
};
// Fix the sock to the screen on scroll and resize events
if ($upgradeToVerifiedButton.length) {
$(window).scroll(fixUpgradeButton).resize(fixUpgradeButton);
// Open the sock when user clicks to Learn More
$toggleActionButton.on('click', () => {
const toggleSpeed = 400;
$toggleActionButton.toggleClass('active');
$verificationSock.slideToggle(toggleSpeed, fixUpgradeButton);
// Toggle aria-expanded attribute
const newAriaExpandedState = $toggleActionButton.attr('aria-expanded') === 'false';
$toggleActionButton.attr('aria-expanded', newAriaExpandedState);
// Log open and close events
const isOpening = $toggleActionButton.hasClass('active');
const logMessage = isOpening ? 'edx.bi.course.sock.toggle_opened'
: 'edx.bi.course.sock.toggle_closed';
window.analytics.track(
logMessage,
{
from_page: pageLocation,
},
);
});
$upgradeToVerifiedButton.on('click', () => {
Logger.log(
'edx.course.enrollment.upgrade.clicked',
{
location: 'sock',
},
);
});
}
// Open the sock when user clicks to Learn More
$toggleActionButton.on('click', () => {
const toggleSpeed = 400;
$toggleActionButton.toggleClass('active');
$verificationSock.slideToggle(toggleSpeed, fixUpgradeButton);
// Toggle aria-expanded attribute
const newAriaExpandedState = $toggleActionButton.attr('aria-expanded') === 'false';
$toggleActionButton.attr('aria-expanded', newAriaExpandedState);
// Log open and close events
const isOpening = $toggleActionButton.hasClass('active');
const logMessage = isOpening ? 'edx.bi.course.sock.toggle_opened'
: 'edx.bi.course.sock.toggle_closed';
window.analytics.track(
logMessage,
{
from_page: pageLocation,
},
);
});
$upgradeToVerifiedButton.on('click', () => {
Logger.log(
'edx.course.enrollment.upgrade.clicked',
{
location: 'sock',
},
);
});
}
}

View File

@@ -3,52 +3,52 @@ import $ from 'jquery'; // eslint-disable-line import/extensions
export class Currency { // eslint-disable-line import/prefer-default-export
editText(price) {
const l10nCookie = this.countryL10nData;
const lmsregex = /(\$)([\d|.]*)( USD)/g;
const priceText = price.text();
const regexMatch = lmsregex.exec(priceText);
if (regexMatch) {
const currentPrice = regexMatch[2];
const dollars = parseFloat(currentPrice);
const newPrice = dollars * l10nCookie.rate;
const newPriceString = `${l10nCookie.symbol}${Math.round(newPrice)} ${l10nCookie.code}`;
// Change displayed price based on edx-price-l10n cookie currency_data
price.text(newPriceString);
editText(price) {
const l10nCookie = this.countryL10nData;
const lmsregex = /(\$)([\d|.]*)( USD)/g;
const priceText = price.text();
const regexMatch = lmsregex.exec(priceText);
if (regexMatch) {
const currentPrice = regexMatch[2];
const dollars = parseFloat(currentPrice);
const newPrice = dollars * l10nCookie.rate;
const newPriceString = `${l10nCookie.symbol}${Math.round(newPrice)} ${l10nCookie.code}`;
// Change displayed price based on edx-price-l10n cookie currency_data
price.text(newPriceString);
}
}
}
setPrice() {
$('.upgrade-price-string').each((i, price) => {
// When the button includes two prices (discounted and previous)
// we call the method twice, since it modifies one price at a time.
// Could also be used to modify all prices on any page
this.editText($(price));
});
}
getCountry() {
try {
this.countryL10nData = JSON.parse($.cookie('edx-price-l10n'));
} catch (e) {
if (e instanceof SyntaxError) {
// If cookie isn't proper JSON, log but continue. This will show the purchase experience
// in a non-local currency but will not prevent the user from interacting with the page.
console.error(e);
console.error("Ignoring malformed 'edx-price-l10n' cookie.");
} else {
throw e;
}
setPrice() {
$('.upgrade-price-string').each((i, price) => {
// When the button includes two prices (discounted and previous)
// we call the method twice, since it modifies one price at a time.
// Could also be used to modify all prices on any page
this.editText($(price));
});
}
if (this.countryL10nData) {
window.analytics.track('edx.bi.user.track_selection.local_currency_cookie_set');
this.setPrice();
}
}
constructor() {
$(document).ready(() => {
this.getCountry();
});
}
getCountry() {
try {
this.countryL10nData = JSON.parse($.cookie('edx-price-l10n'));
} catch (e) {
if (e instanceof SyntaxError) {
// If cookie isn't proper JSON, log but continue. This will show the purchase experience
// in a non-local currency but will not prevent the user from interacting with the page.
console.error(e);
console.error("Ignoring malformed 'edx-price-l10n' cookie.");
} else {
throw e;
}
}
if (this.countryL10nData) {
window.analytics.track('edx.bi.user.track_selection.local_currency_cookie_set');
this.setPrice();
}
}
constructor() {
$(document).ready(() => {
this.getCountry();
});
}
}

View File

@@ -4,56 +4,56 @@ import $ from 'jquery'; // eslint-disable-line import/extensions
import { Currency } from '../currency';
describe('Currency factory', () => {
let currency;
let canadaPosition;
let usaPosition;
let japanPosition;
let currency;
let canadaPosition;
let usaPosition;
let japanPosition;
window.analytics = jasmine.createSpyObj('analytics', ['page', 'track', 'trackLink']);
window.analytics = jasmine.createSpyObj('analytics', ['page', 'track', 'trackLink']);
beforeEach(() => {
loadFixtures('course_experience/fixtures/course-currency-fragment.html');
canadaPosition = {
coords: {
latitude: 58.773884,
longitude: -124.882581,
},
};
usaPosition = {
coords: {
latitude: 42.366202,
longitude: -71.973095,
},
};
japanPosition = {
coords: {
latitude: 35.857826,
longitude: 137.737495,
},
};
$.cookie('edx-price-l10n', null, { path: '/' });
});
beforeEach(() => {
loadFixtures('course_experience/fixtures/course-currency-fragment.html');
canadaPosition = {
coords: {
latitude: 58.773884,
longitude: -124.882581,
},
};
usaPosition = {
coords: {
latitude: 42.366202,
longitude: -71.973095,
},
};
japanPosition = {
coords: {
latitude: 35.857826,
longitude: 137.737495,
},
};
$.cookie('edx-price-l10n', null, { path: '/' });
});
describe('converts price to local currency', () => {
it('when location is the default (US)', () => {
$.cookie('edx-price-l10n', '{"rate":1,"code":"USD","symbol":"$","countryCode":"US"}', { path: '/' });
currency = new Currency();
expect($('[name="verified_mode"].no-discount').filter(':visible').text()).toEqual('Pursue a Verified Certificate($100 USD)');
describe('converts price to local currency', () => {
it('when location is the default (US)', () => {
$.cookie('edx-price-l10n', '{"rate":1,"code":"USD","symbol":"$","countryCode":"US"}', { path: '/' });
currency = new Currency();
expect($('[name="verified_mode"].no-discount').filter(':visible').text()).toEqual('Pursue a Verified Certificate($100 USD)');
});
it('when cookie is set to a different country', () => {
$.cookie('edx-price-l10n', '{"rate":2.2,"code":"CAD","symbol":"$","countryCode":"CAN"}', { expires: 1 });
currency = new Currency();
expect($('[name="verified_mode"].no-discount').filter(':visible').text()).toEqual('Pursue a Verified Certificate($220 CAD)');
});
it('when cookie is set to a different country with a discount', () => {
$.cookie('edx-price-l10n', '{"rate":2.2,"code":"CAD","symbol":"$","countryCode":"CAN"}', { expires: 1 });
currency = new Currency();
expect($('[name="verified_mode"].discount').filter(':visible').text()).toEqual('Pursue a Verified Certificate($198 CAD $220 CAD)');
});
it('should send event on initial load', () => {
$.cookie('edx-price-l10n', '{"rate":1,"code":"USD","symbol":"$","countryCode":"US"}', { path: '/' });
currency = new Currency();
expect(window.analytics.track).toHaveBeenCalledWith('edx.bi.user.track_selection.local_currency_cookie_set');
});
});
it('when cookie is set to a different country', () => {
$.cookie('edx-price-l10n', '{"rate":2.2,"code":"CAD","symbol":"$","countryCode":"CAN"}', { expires: 1 });
currency = new Currency();
expect($('[name="verified_mode"].no-discount').filter(':visible').text()).toEqual('Pursue a Verified Certificate($220 CAD)');
});
it('when cookie is set to a different country with a discount', () => {
$.cookie('edx-price-l10n', '{"rate":2.2,"code":"CAD","symbol":"$","countryCode":"CAN"}', { expires: 1 });
currency = new Currency();
expect($('[name="verified_mode"].discount').filter(':visible').text()).toEqual('Pursue a Verified Certificate($198 CAD $220 CAD)');
});
it('should send event on initial load', () => {
$.cookie('edx-price-l10n', '{"rate":1,"code":"USD","symbol":"$","countryCode":"US"}', { path: '/' });
currency = new Currency();
expect(window.analytics.track).toHaveBeenCalledWith('edx.bi.user.track_selection.local_currency_cookie_set');
});
});
});

View File

@@ -5,57 +5,57 @@
'underscore', 'backbone', 'course_search/js/search_router', 'course_search/js/views/search_form',
'course_search/js/collections/search_collection', 'course_search/js/views/course_search_results_view'
],
function(_, Backbone, SearchRouter, CourseSearchForm, SearchCollection, CourseSearchResultsView) {
return function(options) {
var courseId = options.courseId;
var requestedQuery = options.query;
var supportsActive = options.supportsActive;
var router = new SearchRouter();
var form = new CourseSearchForm({
el: options.searchHeader,
supportsActive: supportsActive
});
var collection = new SearchCollection([], {courseId: courseId});
var results = new CourseSearchResultsView({collection: collection});
var dispatcher = _.clone(Backbone.Events);
function(_, Backbone, SearchRouter, CourseSearchForm, SearchCollection, CourseSearchResultsView) {
return function(options) {
var courseId = options.courseId;
var requestedQuery = options.query;
var supportsActive = options.supportsActive;
var router = new SearchRouter();
var form = new CourseSearchForm({
el: options.searchHeader,
supportsActive: supportsActive
});
var collection = new SearchCollection([], {courseId: courseId});
var results = new CourseSearchResultsView({collection: collection});
var dispatcher = _.clone(Backbone.Events);
dispatcher.listenTo(router, 'search', function(query) {
form.doSearch(query);
});
dispatcher.listenTo(router, 'search', function(query) {
form.doSearch(query);
});
dispatcher.listenTo(form, 'search', function(query) {
results.showLoadingMessage();
collection.performSearch(query);
router.navigate('search/' + query, {replace: true});
});
dispatcher.listenTo(form, 'search', function(query) {
results.showLoadingMessage();
collection.performSearch(query);
router.navigate('search/' + query, {replace: true});
});
dispatcher.listenTo(form, 'clear', function() {
collection.cancelSearch();
results.clear();
router.navigate('');
});
dispatcher.listenTo(form, 'clear', function() {
collection.cancelSearch();
results.clear();
router.navigate('');
});
dispatcher.listenTo(results, 'next', function() {
collection.loadNextPage();
});
dispatcher.listenTo(results, 'next', function() {
collection.loadNextPage();
});
dispatcher.listenTo(collection, 'search', function() {
results.render();
});
dispatcher.listenTo(collection, 'search', function() {
results.render();
});
dispatcher.listenTo(collection, 'next', function() {
results.renderNext();
});
dispatcher.listenTo(collection, 'next', function() {
results.renderNext();
});
dispatcher.listenTo(collection, 'error', function() {
results.showErrorMessage();
});
dispatcher.listenTo(collection, 'error', function() {
results.showErrorMessage();
});
// Perform a search if an initial query has been provided.
if (requestedQuery) {
router.trigger('search', requestedQuery);
}
};
}
// Perform a search if an initial query has been provided.
if (requestedQuery) {
router.trigger('search', requestedQuery);
}
};
}
);
}).call(this, define || RequireJS.define);

View File

@@ -5,51 +5,51 @@
'underscore', 'backbone', 'course_search/js/search_router', 'course_search/js/views/search_form',
'course_search/js/collections/search_collection', 'course_search/js/views/dashboard_search_results_view'
],
function(_, Backbone, SearchRouter, SearchForm, SearchCollection, DashboardSearchResultsView) {
return function() {
var router = new SearchRouter();
var form = new SearchForm({
el: $('#dashboard-search-bar')
});
var collection = new SearchCollection([]);
var results = new DashboardSearchResultsView({collection: collection});
var dispatcher = _.clone(Backbone.Events);
function(_, Backbone, SearchRouter, SearchForm, SearchCollection, DashboardSearchResultsView) {
return function() {
var router = new SearchRouter();
var form = new SearchForm({
el: $('#dashboard-search-bar')
});
var collection = new SearchCollection([]);
var results = new DashboardSearchResultsView({collection: collection});
var dispatcher = _.clone(Backbone.Events);
dispatcher.listenTo(router, 'search', function(query) {
form.doSearch(query);
});
dispatcher.listenTo(router, 'search', function(query) {
form.doSearch(query);
});
dispatcher.listenTo(form, 'search', function(query) {
results.showLoadingMessage();
collection.performSearch(query);
router.navigate('search/' + query, {replace: true});
});
dispatcher.listenTo(form, 'search', function(query) {
results.showLoadingMessage();
collection.performSearch(query);
router.navigate('search/' + query, {replace: true});
});
dispatcher.listenTo(form, 'clear', function() {
collection.cancelSearch();
results.clear();
router.navigate('');
});
dispatcher.listenTo(form, 'clear', function() {
collection.cancelSearch();
results.clear();
router.navigate('');
});
dispatcher.listenTo(results, 'next', function() {
collection.loadNextPage();
});
dispatcher.listenTo(results, 'next', function() {
collection.loadNextPage();
});
dispatcher.listenTo(results, 'reset', function() {
form.resetSearchForm();
});
dispatcher.listenTo(results, 'reset', function() {
form.resetSearchForm();
});
dispatcher.listenTo(collection, 'search', function() {
results.render();
});
dispatcher.listenTo(collection, 'search', function() {
results.render();
});
dispatcher.listenTo(collection, 'next', function() {
results.renderNext();
});
dispatcher.listenTo(collection, 'next', function() {
results.renderNext();
});
dispatcher.listenTo(collection, 'error', function() {
results.showErrorMessage();
});
};
});
dispatcher.listenTo(collection, 'error', function() {
results.showErrorMessage();
});
};
});
}(define || RequireJS.define));

View File

@@ -61,7 +61,7 @@
return this;
},
/**
/**
* Redirect to a URL. Mainly useful for mocking out in tests.
* @param {string} url The URL to redirect to.
*/

View File

@@ -13,7 +13,7 @@ define(
'js/views/message_banner'
],
function(Backbone, $, _, AjaxHelpers, TemplateHelpers, Helpers, LearnerProfileHelpers, FieldViews,
UserAccountModel, UserPreferencesModel, LearnerProfileView, LearnerProfileFields, LearnerProfilePage) {
UserAccountModel, UserPreferencesModel, LearnerProfileView, LearnerProfileFields, LearnerProfilePage) {
'use strict';
describe('edx.user.LearnerProfileFactory', function() {

View File

@@ -8,92 +8,92 @@ define([
'learner_profile/js/spec_helpers/helpers',
'learner_profile/js/views/badge_list_container'
],
function(Backbone, $, _, URI, AjaxHelpers, PagingCollection, LearnerProfileHelpers, BadgeListContainer) {
'use strict';
function(Backbone, $, _, URI, AjaxHelpers, PagingCollection, LearnerProfileHelpers, BadgeListContainer) {
'use strict';
describe('edx.user.BadgeListContainer', function() {
var view;
describe('edx.user.BadgeListContainer', function() {
var view;
var createView = function(requests, pageNum, badgeListObject) {
var BadgeCollection = PagingCollection.extend({
queryParams: {
currentPage: 'current_page'
}
});
var badgeCollection = new BadgeCollection();
var models = [];
var badgeListContainer;
var request;
var path;
badgeCollection.url = '/api/badges/v1/assertions/user/staff/';
_.each(_.range(badgeListObject.count), function(idx) {
models.push(LearnerProfileHelpers.makeBadge(idx));
});
badgeListObject.results = models; // eslint-disable-line no-param-reassign
badgeCollection.setPage(pageNum);
request = AjaxHelpers.currentRequest(requests);
path = new URI(request.url).path();
expect(path).toBe('/api/badges/v1/assertions/user/staff/');
AjaxHelpers.respondWithJson(requests, badgeListObject);
badgeListContainer = new BadgeListContainer({
collection: badgeCollection
});
badgeListContainer.render();
return badgeListContainer;
};
afterEach(function() {
view.$el.remove();
var createView = function(requests, pageNum, badgeListObject) {
var BadgeCollection = PagingCollection.extend({
queryParams: {
currentPage: 'current_page'
}
});
it('displays all badges', function() {
var requests = AjaxHelpers.requests(this),
badges;
view = createView(requests, 1, {
count: 30,
previous: '/arbitrary/url',
num_pages: 3,
next: null,
start: 20,
current_page: 1,
results: []
});
badges = view.$el.find('div.badge-display');
expect(badges.length).toBe(30);
var badgeCollection = new BadgeCollection();
var models = [];
var badgeListContainer;
var request;
var path;
badgeCollection.url = '/api/badges/v1/assertions/user/staff/';
_.each(_.range(badgeListObject.count), function(idx) {
models.push(LearnerProfileHelpers.makeBadge(idx));
});
badgeListObject.results = models; // eslint-disable-line no-param-reassign
badgeCollection.setPage(pageNum);
request = AjaxHelpers.currentRequest(requests);
path = new URI(request.url).path();
expect(path).toBe('/api/badges/v1/assertions/user/staff/');
AjaxHelpers.respondWithJson(requests, badgeListObject);
badgeListContainer = new BadgeListContainer({
collection: badgeCollection
it('displays placeholder on last page', function() {
var requests = AjaxHelpers.requests(this),
placeholder;
view = createView(requests, 3, {
count: 30,
previous: '/arbitrary/url',
num_pages: 3,
next: null,
start: 20,
current_page: 3,
results: []
});
placeholder = view.$el.find('span.accomplishment-placeholder');
expect(placeholder.length).toBe(1);
});
badgeListContainer.render();
return badgeListContainer;
};
it('does not display placeholder on first page', function() {
var requests = AjaxHelpers.requests(this),
placeholder;
view = createView(requests, 1, {
count: 30,
previous: '/arbitrary/url',
num_pages: 3,
next: null,
start: 0,
current_page: 1,
results: []
});
placeholder = view.$el.find('span.accomplishment-placeholder');
expect(placeholder.length).toBe(0);
});
afterEach(function() {
view.$el.remove();
});
}
it('displays all badges', function() {
var requests = AjaxHelpers.requests(this),
badges;
view = createView(requests, 1, {
count: 30,
previous: '/arbitrary/url',
num_pages: 3,
next: null,
start: 20,
current_page: 1,
results: []
});
badges = view.$el.find('div.badge-display');
expect(badges.length).toBe(30);
});
it('displays placeholder on last page', function() {
var requests = AjaxHelpers.requests(this),
placeholder;
view = createView(requests, 3, {
count: 30,
previous: '/arbitrary/url',
num_pages: 3,
next: null,
start: 20,
current_page: 3,
results: []
});
placeholder = view.$el.find('span.accomplishment-placeholder');
expect(placeholder.length).toBe(1);
});
it('does not display placeholder on first page', function() {
var requests = AjaxHelpers.requests(this),
placeholder;
view = createView(requests, 1, {
count: 30,
previous: '/arbitrary/url',
num_pages: 3,
next: null,
start: 0,
current_page: 1,
results: []
});
placeholder = view.$el.find('span.accomplishment-placeholder');
expect(placeholder.length).toBe(0);
});
});
}
);

View File

@@ -6,77 +6,77 @@ define([
'learner_profile/js/spec_helpers/helpers',
'learner_profile/js/views/badge_list_view'
],
function(Backbone, $, _, PagingCollection, LearnerProfileHelpers, BadgeListView) {
'use strict';
function(Backbone, $, _, PagingCollection, LearnerProfileHelpers, BadgeListView) {
'use strict';
describe('edx.user.BadgeListView', function() {
var view;
describe('edx.user.BadgeListView', function() {
var view;
var createView = function(badges, pages, page, hasNextPage) {
var badgeCollection = new PagingCollection();
var models = [];
var badgeList;
badgeCollection.url = '/api/badges/v1/assertions/user/staff/';
_.each(badges, function(element) {
models.push(new Backbone.Model(element));
});
badgeCollection.models = models;
badgeCollection.length = badges.length;
badgeCollection.currentPage = page;
badgeCollection.totalPages = pages;
badgeCollection.hasNextPage = function() {
return hasNextPage;
};
badgeList = new BadgeListView({
collection: badgeCollection
});
return badgeList;
var createView = function(badges, pages, page, hasNextPage) {
var badgeCollection = new PagingCollection();
var models = [];
var badgeList;
badgeCollection.url = '/api/badges/v1/assertions/user/staff/';
_.each(badges, function(element) {
models.push(new Backbone.Model(element));
});
badgeCollection.models = models;
badgeCollection.length = badges.length;
badgeCollection.currentPage = page;
badgeCollection.totalPages = pages;
badgeCollection.hasNextPage = function() {
return hasNextPage;
};
badgeList = new BadgeListView({
collection: badgeCollection
afterEach(function() {
view.$el.remove();
});
return badgeList;
};
it('there is a single row if there is only one badge', function() {
var rows;
view = createView([LearnerProfileHelpers.makeBadge(1)], 1, 1, false);
view.render();
rows = view.$el.find('div.row');
expect(rows.length).toBe(1);
});
it('accomplishments placeholder is visible on a last page', function() {
var placeholder;
view = createView([LearnerProfileHelpers.makeBadge(1)], 2, 2, false);
view.render();
placeholder = view.$el.find('span.accomplishment-placeholder');
expect(placeholder.length).toBe(1);
});
it('accomplishments placeholder to be not visible on a first page', function() {
var placeholder;
view = createView([LearnerProfileHelpers.makeBadge(1)], 1, 2, true);
view.render();
placeholder = view.$el.find('span.accomplishment-placeholder');
expect(placeholder.length).toBe(0);
});
it('badges are in two columns (checked by counting rows for a known number of badges)', function() {
var badges = [];
var placeholder;
var rows;
_.each(_.range(4), function(item) {
badges.push(LearnerProfileHelpers.makeBadge(item));
});
view = createView(badges, 1, 2, true);
view.render();
placeholder = view.$el.find('span.accomplishment-placeholder');
expect(placeholder.length).toBe(0);
rows = view.$el.find('div.row');
expect(rows.length).toBe(2);
});
afterEach(function() {
view.$el.remove();
});
}
it('there is a single row if there is only one badge', function() {
var rows;
view = createView([LearnerProfileHelpers.makeBadge(1)], 1, 1, false);
view.render();
rows = view.$el.find('div.row');
expect(rows.length).toBe(1);
});
it('accomplishments placeholder is visible on a last page', function() {
var placeholder;
view = createView([LearnerProfileHelpers.makeBadge(1)], 2, 2, false);
view.render();
placeholder = view.$el.find('span.accomplishment-placeholder');
expect(placeholder.length).toBe(1);
});
it('accomplishments placeholder to be not visible on a first page', function() {
var placeholder;
view = createView([LearnerProfileHelpers.makeBadge(1)], 1, 2, true);
view.render();
placeholder = view.$el.find('span.accomplishment-placeholder');
expect(placeholder.length).toBe(0);
});
it('badges are in two columns (checked by counting rows for a known number of badges)', function() {
var badges = [];
var placeholder;
var rows;
_.each(_.range(4), function(item) {
badges.push(LearnerProfileHelpers.makeBadge(item));
});
view = createView(badges, 1, 2, true);
view.render();
placeholder = view.$el.find('span.accomplishment-placeholder');
expect(placeholder.length).toBe(0);
rows = view.$el.find('div.row');
expect(rows.length).toBe(2);
});
});
}
);

View File

@@ -3,112 +3,112 @@ define([
'learner_profile/js/spec_helpers/helpers',
'learner_profile/js/views/badge_view'
],
function(Backbone, $, _, LearnerProfileHelpers, BadgeView) {
'use strict';
function(Backbone, $, _, LearnerProfileHelpers, BadgeView) {
'use strict';
describe('edx.user.BadgeView', function() {
var view,
badge,
testBadgeNameIsDisplayed,
testBadgeIconIsDisplayed;
describe('edx.user.BadgeView', function() {
var view,
badge,
testBadgeNameIsDisplayed,
testBadgeIconIsDisplayed;
var createView = function(ownProfile) {
var options,
testView;
badge = LearnerProfileHelpers.makeBadge(1);
options = {
model: new Backbone.Model(badge),
ownProfile: ownProfile,
badgeMeta: {}
};
testView = new BadgeView(options);
testView.render();
$('body').append(testView.$el);
testView.$el.show();
expect(testView.$el.is(':visible')).toBe(true);
return testView;
var createView = function(ownProfile) {
var options,
testView;
badge = LearnerProfileHelpers.makeBadge(1);
options = {
model: new Backbone.Model(badge),
ownProfile: ownProfile,
badgeMeta: {}
};
testView = new BadgeView(options);
testView.render();
$('body').append(testView.$el);
testView.$el.show();
expect(testView.$el.is(':visible')).toBe(true);
return testView;
};
afterEach(function() {
view.$el.remove();
$('.badges-modal').remove();
});
it('profile of other has no share button', function() {
view = createView(false);
expect(view.context.ownProfile).toBeFalsy();
expect(view.$el.find('button.share-button').length).toBe(0);
});
it('own profile has share button', function() {
view = createView(true);
expect(view.context.ownProfile).toBeTruthy();
expect(view.$el.find('button.share-button').length).toBe(1);
});
it('click on share button calls createModal function', function() {
var shareButton;
view = createView(true);
spyOn(view, 'createModal');
view.delegateEvents();
expect(view.context.ownProfile).toBeTruthy();
shareButton = view.$el.find('button.share-button');
expect(shareButton.length).toBe(1);
expect(view.createModal).not.toHaveBeenCalled();
shareButton.click();
expect(view.createModal).toHaveBeenCalled();
});
it('click on share button calls shows the dialog', function(done) {
var shareButton,
$modalElement;
view = createView(true);
expect(view.context.ownProfile).toBeTruthy();
shareButton = view.$el.find('button.share-button');
expect(shareButton.length).toBe(1);
$modalElement = $('.badges-modal');
expect($modalElement.length).toBe(0);
expect($modalElement.is(':visible')).toBeFalsy();
shareButton.click();
// Note: this element should have appeared in the dom during: shareButton.click();
$modalElement = $('.badges-modal');
jasmine.waitUntil(function() {
return $modalElement.is(':visible');
}).always(done);
});
testBadgeNameIsDisplayed = function(ownProfile) {
var badgeDiv;
view = createView(ownProfile);
badgeDiv = view.$el.find('.badge-name');
expect(badgeDiv.length).toBeTruthy();
expect(badgeDiv.is(':visible')).toBe(true);
expect(_.count(badgeDiv.html(), badge.badge_class.display_name)).toBeTruthy();
};
it('test badge name is displayed for own profile', function() {
testBadgeNameIsDisplayed(true);
});
it('test badge name is displayed for other profile', function() {
testBadgeNameIsDisplayed(false);
});
testBadgeIconIsDisplayed = function(ownProfile) {
var badgeImg;
view = createView(ownProfile);
badgeImg = view.$el.find('img.badge');
expect(badgeImg.length).toBe(1);
expect(badgeImg.attr('src')).toEqual(badge.image_url);
};
it('test badge icon is displayed for own profile', function() {
testBadgeIconIsDisplayed(true);
});
it('test badge icon is displayed for other profile', function() {
testBadgeIconIsDisplayed(false);
});
afterEach(function() {
view.$el.remove();
$('.badges-modal').remove();
});
}
it('profile of other has no share button', function() {
view = createView(false);
expect(view.context.ownProfile).toBeFalsy();
expect(view.$el.find('button.share-button').length).toBe(0);
});
it('own profile has share button', function() {
view = createView(true);
expect(view.context.ownProfile).toBeTruthy();
expect(view.$el.find('button.share-button').length).toBe(1);
});
it('click on share button calls createModal function', function() {
var shareButton;
view = createView(true);
spyOn(view, 'createModal');
view.delegateEvents();
expect(view.context.ownProfile).toBeTruthy();
shareButton = view.$el.find('button.share-button');
expect(shareButton.length).toBe(1);
expect(view.createModal).not.toHaveBeenCalled();
shareButton.click();
expect(view.createModal).toHaveBeenCalled();
});
it('click on share button calls shows the dialog', function(done) {
var shareButton,
$modalElement;
view = createView(true);
expect(view.context.ownProfile).toBeTruthy();
shareButton = view.$el.find('button.share-button');
expect(shareButton.length).toBe(1);
$modalElement = $('.badges-modal');
expect($modalElement.length).toBe(0);
expect($modalElement.is(':visible')).toBeFalsy();
shareButton.click();
// Note: this element should have appeared in the dom during: shareButton.click();
$modalElement = $('.badges-modal');
jasmine.waitUntil(function() {
return $modalElement.is(':visible');
}).always(done);
});
testBadgeNameIsDisplayed = function(ownProfile) {
var badgeDiv;
view = createView(ownProfile);
badgeDiv = view.$el.find('.badge-name');
expect(badgeDiv.length).toBeTruthy();
expect(badgeDiv.is(':visible')).toBe(true);
expect(_.count(badgeDiv.html(), badge.badge_class.display_name)).toBeTruthy();
};
it('test badge name is displayed for own profile', function() {
testBadgeNameIsDisplayed(true);
});
it('test badge name is displayed for other profile', function() {
testBadgeNameIsDisplayed(false);
});
testBadgeIconIsDisplayed = function(ownProfile) {
var badgeImg;
view = createView(ownProfile);
badgeImg = view.$el.find('img.badge');
expect(badgeImg.length).toBe(1);
expect(badgeImg.attr('src')).toEqual(badge.image_url);
};
it('test badge icon is displayed for own profile', function() {
testBadgeIconIsDisplayed(true);
});
it('test badge icon is displayed for other profile', function() {
testBadgeIconIsDisplayed(false);
});
});
}
);

View File

@@ -11,7 +11,7 @@ define(
'js/views/message_banner'
],
function(Backbone, $, _, AjaxHelpers, TemplateHelpers, Helpers, UserAccountModel, LearnerProfileFields,
MessageBannerView) {
MessageBannerView) {
'use strict';
describe('edx.user.LearnerProfileFields', function() {

View File

@@ -20,8 +20,8 @@ define(
'js/views/message_banner'
],
function(gettext, Backbone, $, _, PagingCollection, AjaxHelpers, TemplateHelpers, Helpers, LearnerProfileHelpers,
FieldViews, UserAccountModel, AccountPreferencesModel, LearnerProfileFields, LearnerProfileView,
BadgeListContainer, AccountSettingsFieldViews, MessageBannerView) {
FieldViews, UserAccountModel, AccountPreferencesModel, LearnerProfileFields, LearnerProfileView,
BadgeListContainer, AccountSettingsFieldViews, MessageBannerView) {
'use strict';
describe('edx.user.LearnerProfileView', function() {

View File

@@ -10,56 +10,56 @@
'learner_profile/js/views/badge_view',
'text!learner_profile/templates/badge_placeholder.underscore'
],
function(gettext, $, _, HtmlUtils, ListView, BadgeView, badgePlaceholder) {
var BadgeListView = ListView.extend({
tagName: 'div',
function(gettext, $, _, HtmlUtils, ListView, BadgeView, badgePlaceholder) {
var BadgeListView = ListView.extend({
tagName: 'div',
template: HtmlUtils.template(badgePlaceholder),
template: HtmlUtils.template(badgePlaceholder),
renderCollection: function() {
var self = this,
$row;
renderCollection: function() {
var self = this,
$row;
this.$el.empty();
this.$el.empty();
// Split into two columns.
this.collection.each(function(badge, index) {
var $item;
if (index % 2 === 0) {
$row = $('<div class="row">');
this.$el.append($row);
}
$item = new BadgeView({
model: badge,
badgeMeta: this.badgeMeta,
ownProfile: this.ownProfile
}).render().el;
if ($row) {
$row.append($item);
}
this.itemViews.push($item);
}, this);
// Placeholder must always be at the end, and may need a new row.
if (!this.collection.hasNextPage()) {
// find_courses_url set by BadgeListContainer during initialization.
if (this.collection.length % 2 === 0) {
$row = $('<div class="row">');
this.$el.append($row);
}
if ($row) {
HtmlUtils.append(
$row,
this.template({find_courses_url: self.find_courses_url})
);
}
// Split into two columns.
this.collection.each(function(badge, index) {
var $item;
if (index % 2 === 0) {
$row = $('<div class="row">');
this.$el.append($row);
}
return this;
}
});
$item = new BadgeView({
model: badge,
badgeMeta: this.badgeMeta,
ownProfile: this.ownProfile
}).render().el;
return BadgeListView;
if ($row) {
$row.append($item);
}
this.itemViews.push($item);
}, this);
// Placeholder must always be at the end, and may need a new row.
if (!this.collection.hasNextPage()) {
// find_courses_url set by BadgeListContainer during initialization.
if (this.collection.length % 2 === 0) {
$row = $('<div class="row">');
this.$el.append($row);
}
if ($row) {
HtmlUtils.append(
$row,
this.template({find_courses_url: self.find_courses_url})
);
}
}
return this;
}
});
return BadgeListView;
});
}).call(this, define || RequireJS.define);