Jasmine tests
This commit is contained in:
@@ -1,12 +0,0 @@
|
||||
<div class="course-wrapper">
|
||||
<header id="open_close_accordion">
|
||||
<a href="#">close</a>
|
||||
</header>
|
||||
<div id="accordion">
|
||||
<button class="chapter">
|
||||
<h3>
|
||||
Introduction Chapter
|
||||
</h3>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,10 +1,5 @@
|
||||
describe 'Courseware', ->
|
||||
describe 'start', ->
|
||||
it 'create the navigation', ->
|
||||
spyOn(window, 'Navigation')
|
||||
Courseware.start()
|
||||
expect(window.Navigation).toHaveBeenCalled()
|
||||
|
||||
it 'binds the Logger', ->
|
||||
spyOn(Logger, 'bind')
|
||||
Courseware.start()
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
describe 'Navigation', ->
|
||||
beforeEach ->
|
||||
loadFixtures 'coffee/fixtures/accordion.html'
|
||||
@navigation = new Navigation
|
||||
|
||||
describe 'constructor', ->
|
||||
describe 'when the #accordion exists', ->
|
||||
describe 'when there is an active section', ->
|
||||
beforeEach ->
|
||||
spyOn $.fn, 'accordion'
|
||||
$('#accordion').append('<div><div><ol><li></li></ol></div></div><div><div><ol><li class="active"></li></ol></div></div>')
|
||||
new Navigation
|
||||
|
||||
it 'activate the accordion with correct active section', ->
|
||||
expect($('#accordion').accordion).toHaveBeenCalledWith
|
||||
active: 1
|
||||
header: 'h3'
|
||||
autoHeight: false
|
||||
heightStyle: 'content'
|
||||
|
||||
describe 'when there is no active section', ->
|
||||
beforeEach ->
|
||||
spyOn $.fn, 'accordion'
|
||||
$('#accordion').append('<div><div><ol><li></li></ol></div></div><div><div><ol><li></li></ol></div></div>')
|
||||
new Navigation
|
||||
|
||||
it 'activate the accordian with no section as active', ->
|
||||
expect($('#accordion').accordion).toHaveBeenCalledWith
|
||||
active: 0
|
||||
header: 'h3'
|
||||
autoHeight: false
|
||||
heightStyle: 'content'
|
||||
|
||||
it 'binds the accordionchange event', ->
|
||||
expect($('#accordion')).toHandleWith 'accordionchange', @navigation.log
|
||||
|
||||
it 'bind the navigation toggle', ->
|
||||
expect($('#open_close_accordion a')).toHandleWith 'click', @navigation.toggle
|
||||
|
||||
it 'bind the setChapter', ->
|
||||
expect($('#accordion .chapter')).toHandleWith 'click', @navigation.setChapter
|
||||
|
||||
describe 'when the #accordion does not exists', ->
|
||||
beforeEach ->
|
||||
$('#accordion').remove()
|
||||
|
||||
it 'does not activate the accordion', ->
|
||||
spyOn $.fn, 'accordion'
|
||||
expect($('#accordion').accordion).wasNotCalled()
|
||||
|
||||
describe 'toggle', ->
|
||||
it 'toggle closed class on the wrapper', ->
|
||||
$('.course-wrapper').removeClass('closed')
|
||||
|
||||
@navigation.toggle()
|
||||
expect($('.course-wrapper')).toHaveClass('closed')
|
||||
|
||||
@navigation.toggle()
|
||||
expect($('.course-wrapper')).not.toHaveClass('closed')
|
||||
|
||||
describe 'log', ->
|
||||
beforeEach ->
|
||||
spyOn Logger, 'log'
|
||||
|
||||
it 'submit event log', ->
|
||||
@navigation.log {}, {
|
||||
newHeader:
|
||||
text: -> "new"
|
||||
oldHeader:
|
||||
text: -> "old"
|
||||
}
|
||||
|
||||
expect(Logger.log).toHaveBeenCalledWith 'accordion',
|
||||
newheader: 'new'
|
||||
oldheader: 'old'
|
||||
|
||||
describe 'setChapter', ->
|
||||
beforeEach ->
|
||||
$('#accordion').append('<div><div><ol><li class="active"><a href="#"></a></li></ol></div></div>')
|
||||
new Navigation
|
||||
it 'Chapter opened', ->
|
||||
e = jQuery.Event('click')
|
||||
$('#accordion .chapter').trigger(e)
|
||||
expect($('.chapter')).toHaveClass('is-open')
|
||||
|
||||
it 'content active on chapter opened', ->
|
||||
e = jQuery.Event('click')
|
||||
$('#accordion .chapter').trigger(e)
|
||||
expect($('.chapter').next('div').children('div')).toHaveClass('ui-accordion-content-active')
|
||||
expect($('.ui-accordion-content-active')).toHaveAttr('aria-hidden', 'false')
|
||||
|
||||
it 'focus move to first child on chapter opened', ->
|
||||
spyOn($.fn, 'focus')
|
||||
e = jQuery.Event('click')
|
||||
$('#accordion .chapter').trigger(e)
|
||||
expect($('.ui-accordion-content-active li:first-child a').focus).toHaveBeenCalled()
|
||||
|
||||
@@ -2,7 +2,6 @@ class @Courseware
|
||||
@prefix: ''
|
||||
|
||||
constructor: ->
|
||||
new Navigation
|
||||
Logger.bind()
|
||||
@render()
|
||||
|
||||
|
||||
47
lms/static/js/fixtures/accordion.html
Normal file
47
lms/static/js/fixtures/accordion.html
Normal file
@@ -0,0 +1,47 @@
|
||||
<div class="course-wrapper">
|
||||
<header id="open_close_accordion">
|
||||
<a href="#">close</a>
|
||||
</header>
|
||||
<div id="accordion">
|
||||
<button class="button-chapter chapter" aria-controls="accordion-menu-1" aria-pressed="true">
|
||||
<h3 class="group-heading">
|
||||
Introduction Chapter
|
||||
</h3>
|
||||
</button>
|
||||
<div class="chapter-content-container" tabindex="-1" aria-expanded="true">
|
||||
<div class="chapter-menu" id="accordion-menu-1">
|
||||
<a href="http://www.edx.org">
|
||||
<p>edX Homepage</p>
|
||||
<p class="subtitle">Ungraded</p>
|
||||
</a>
|
||||
<a class="active" href="http://blog.edx.org">
|
||||
<p>The edX Blog</p>
|
||||
</a>
|
||||
<a class="graded" href="http://courses.edx.org">
|
||||
<p>Courses Dashboard</p>
|
||||
<p class="subtitle">Graded</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<button class="button-chapter chapter" aria-controls="accordion-menu-2" aria-pressed="false">
|
||||
<h3 class="group-heading">
|
||||
Another Chapter
|
||||
</h3>
|
||||
</button>
|
||||
<div class="chapter-content-container" tabindex="-1" aria-expanded="false">
|
||||
<div class="chapter-menu" id="accordion-menu-2">
|
||||
<a href="http://www.edx.org">
|
||||
<p>edX Homepage</p>
|
||||
<p class="subtitle">Ungraded</p>
|
||||
</a>
|
||||
<a href="http://blog.edx.org">
|
||||
<p>The edX Blog</p>
|
||||
</a>
|
||||
<a class="graded" href="http://courses.edx.org">
|
||||
<p>Courses Dashboard</p>
|
||||
<p class="subtitle">Graded</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -64,6 +64,7 @@
|
||||
'_split': 'js/split',
|
||||
'mathjax_delay_renderer': 'coffee/src/mathjax_delay_renderer',
|
||||
'MathJaxProcessor': 'coffee/src/customwmd',
|
||||
'js/utils/navigation': 'js/utils/navigation',
|
||||
|
||||
// Manually specify LMS files that are not converted to RequireJS
|
||||
'history': 'js/vendor/history',
|
||||
@@ -803,6 +804,8 @@
|
||||
'lms/include/teams/js/spec/views/topic_teams_spec.js',
|
||||
'lms/include/teams/js/spec/views/topics_spec.js',
|
||||
'lms/include/teams/js/spec/views/team_profile_header_actions_spec.js'
|
||||
'lms/include/teams/js/spec/views/team_join_spec.js',
|
||||
'lms/include/js/spec/navigation_spec.js'
|
||||
]);
|
||||
|
||||
}).call(this, requirejs, define);
|
||||
|
||||
74
lms/static/js/spec/navigation_spec.js
Normal file
74
lms/static/js/spec/navigation_spec.js
Normal file
@@ -0,0 +1,74 @@
|
||||
define(['jquery', 'js/utils/navigation'], function($) {
|
||||
'use strict';
|
||||
|
||||
describe('Course Navigation Accordion', function() {
|
||||
var accordion, button, heading, chapterContent, chapterMenu;
|
||||
|
||||
beforeEach(function() {
|
||||
loadFixtures('js/fixtures/accordion.html');
|
||||
|
||||
accordion = $('#accordion');
|
||||
button = accordion.children('.button-chapter');
|
||||
heading = button.children('.group-heading');
|
||||
chapterContent = accordion.children('.chapter-content-container');
|
||||
chapterMenu = chapterContent.children('.chapter-menu');
|
||||
|
||||
spyOn($.fn, 'focus').andCallThrough();
|
||||
edx.util.navigation.init();
|
||||
});
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
describe('always', function() {
|
||||
|
||||
it('ensures accordion is present', function() {
|
||||
expect(accordion.length).toBe(1);
|
||||
});
|
||||
|
||||
it('ensures aria attributes are present', function() {
|
||||
expect(button).toHaveAttr({
|
||||
'aria-pressed': 'true'
|
||||
});
|
||||
|
||||
expect(chapterContent).toHaveAttr({
|
||||
'aria-expanded': 'true'
|
||||
});
|
||||
});
|
||||
|
||||
it('ensures only one active item', function() {
|
||||
expect(chapterMenu.find('.active').length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('open section', function() {
|
||||
|
||||
it('ensures new section is opened and previous section is closed', function() {
|
||||
button.last().click();
|
||||
|
||||
expect(chapterContent.first()).toBeHidden();
|
||||
expect(chapterContent.last()).not.toBeHidden();
|
||||
|
||||
expect(button.first()).not.toHaveClass('is-open');
|
||||
expect(button.last()).toHaveClass('is-open');
|
||||
|
||||
expect(chapterContent.last().focus).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('ensure proper aria and attrs', function() {
|
||||
expect(button.last()).toHaveAttr({
|
||||
'aria-pressed': 'false'
|
||||
});
|
||||
expect(button.first()).toHaveAttr({
|
||||
'aria-pressed': 'true'
|
||||
});
|
||||
expect(chapterContent.last()).toHaveAttr({
|
||||
'aria-expanded': 'false'
|
||||
});
|
||||
expect(chapterContent.first()).toHaveAttr({
|
||||
'aria-expanded': 'true'
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
89
lms/static/js/utils/navigation.js
Normal file
89
lms/static/js/utils/navigation.js
Normal file
@@ -0,0 +1,89 @@
|
||||
var edx = edx || {},
|
||||
|
||||
Navigation = (function() {
|
||||
|
||||
var navigation = {
|
||||
|
||||
init: function() {
|
||||
|
||||
if ($('#accordion').length) {
|
||||
|
||||
navigation.openAccordion();
|
||||
navigation.checkForCurrent();
|
||||
navigation.listenForClick();
|
||||
}
|
||||
},
|
||||
|
||||
openAccordion: function() {
|
||||
$('#open_close_accordion a').click();
|
||||
$('.course-wrapper').toggleClass('closed');
|
||||
$('#accordion').show();
|
||||
},
|
||||
|
||||
checkForCurrent: function() {
|
||||
var active;
|
||||
|
||||
active = $('#accordion div div:has(a.active)').index('#accordion div div');
|
||||
|
||||
if (active < 0) {
|
||||
active = $('#accordion group-heading.active').index('#accordion h3');
|
||||
}
|
||||
|
||||
if (active < 0) {
|
||||
active = 0;
|
||||
}
|
||||
|
||||
if (active > 0) {
|
||||
$('#accordion').find('.button-chapter:eq(' + active + ')').trigger('click');
|
||||
}
|
||||
},
|
||||
|
||||
listenForClick: function() {
|
||||
$('#accordion').on('click', '.button-chapter', function(event) {
|
||||
// close and reset all accrdions
|
||||
navigation.resetAllAccordions();
|
||||
|
||||
// open this accordion and send focus
|
||||
navigation.openAccordionSection(event.currentTarget);
|
||||
|
||||
// assign classes and set open aria
|
||||
navigation.setAriaAttrs(event.currentTarget);
|
||||
});
|
||||
},
|
||||
|
||||
resetAllAccordions: function() {
|
||||
$('.chapter-content-container').hide();
|
||||
$('.chapter-content-container .chapter-menu').hide();
|
||||
|
||||
$('#accordion .button-chapter').each(function(event) {
|
||||
$(this).removeClass('is-open').attr('aria-pressed', 'false');
|
||||
$(this).next('.chapter-content-container').attr('aria-expanded', 'false');
|
||||
$(this).children('.group-heading').removeClass('active');
|
||||
$(this).children('.group-heading').find('.icon').addClass('fa-caret-right').removeClass('fa-caret-down');
|
||||
});
|
||||
},
|
||||
|
||||
openAccordionSection: function(section) {
|
||||
$(section).next('.chapter-content-container').show().focus();
|
||||
$(section).next('.chapter-content-container').find('.chapter-menu').show();
|
||||
|
||||
navigation.setAriaAttrs(section);
|
||||
},
|
||||
|
||||
setAriaAttrs: function(section) {
|
||||
$(section).addClass('is-open').attr('aria-pressed', 'true');
|
||||
$(section).next('.chapter-content-container').attr('aria-expanded', 'true');
|
||||
$(section).children('.group-heading').addClass('active');
|
||||
$(section).children('.group-heading').find('.icon').removeClass('fa-caret-right').addClass('fa-caret-down');
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
init: navigation.init
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
edx.util = edx.util || {};
|
||||
edx.util.navigation = Navigation;
|
||||
edx.util.navigation.init();
|
||||
@@ -159,6 +159,7 @@ from branding import api as branding_api
|
||||
|
||||
<%block name="js_extra"/>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/noreferrer.js')}" charset="utf-8"></script>
|
||||
<script type="text/javascript" src="${static.url('coffee/src/navigation.js')}" charset="utf-8"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user