coins-logon-widget
Version:
COINS Logon Widget. Injectable utility to manage browser authorization with COINS
350 lines (295 loc) • 10 kB
JavaScript
var test = require('tape');
var CoinsLogonWidget = require('../scripts/coins-logon-widget.js');
var cookies = require('js-cookie');
var html = require('html-loader!./index.html');
var jQuery = require('jquery');
var messages = require('../scripts/lib/messages.js');
var Promise = this.Promise = require('bluebird'); // phantomJS polyfill. seriously. :-|
var testUtils = require('./test-utils');
/**
* Bind polyfill for PhantomJS.
* {@link https://github.com/Raynos/function-bind}
*/
if (!('bind' in Function)) {
Function.prototype.bind = require('function-bind');
}
jQuery(window.document.body).append(html);
test('constructor, basic', function(t) {
var el = document.getElementById('regular_form');
var myWidget = testUtils.widgetFactory({
el: el,
});
t.ok(myWidget, 'constructor returns a widget');
t.equal(myWidget.element, el, 'constructor sets el');
t.ok(jQuery('#regular_form.coins-logon-widget:visible').length, 'form visible on DOM');
testUtils.teardownWidget(myWidget);
t.end();
});
test('constructor, hiddenLabels', function(t) {
var el = document.getElementById('hidden_labels_form');
var myWidget = testUtils.widgetFactory({
el: el,
hiddenLabels: true,
});
t.equal(
2,
jQuery('#hidden_labels_form .coins-logon-widget-label').length,
'hidden label DOMs nodes present for both un and pw inputs'
);
testUtils.teardownWidget(myWidget);
// visuallyhidden class doesn't actually hide elements, so omit doing
// vis test. x-browser :visible JQ query selector seems to have varying
// results in diff browsers
t.end();
});
// Test for a bug where the widget's username and password fields flip order
// every other time the widget is displayed. The test's structure mimics COINS's
// `clientAuthTimer` module, where the bug occurs.
test('field order', function(t) {
var $target = jQuery('#field_order_form');
var tempId = 'field_order_form_temp';
var myModule = {
showWidget: function() {
$target.append('<div id="' + tempId + '"></div>');
myModule.logonWidget = testUtils.widgetFactory({
el: document.getElementById(tempId),
});
myModule.logonWidget.removeAllListeners();
$target.fadeIn();
},
removeWidget: function() {
var $temp = jQuery('#' + tempId);
$temp.fadeOut(function() {
$temp.remove();
});
myModule.logonWidget.destroy();
myModule.logonWidget = null;
},
};
function getFirstInputName() {
return jQuery('#' + tempId + ' input').eq(0).attr('name');
}
myModule.showWidget();
t.equal(getFirstInputName(), 'username', 'Username input is first');
myModule.removeWidget();
myModule.showWidget();
t.equal(getFirstInputName(), 'username', 'User input is still first');
testUtils.teardownWidget(myModule.logonWidget);
t.end();
});
test('api activity', { timeout: 2000 }, function(t) {
t.plan(1);
var el = document.getElementById('api_call_form');
var myWidget = testUtils.widgetFactory({
el: el,
baseUrl: 'http://localhost:12354',
authCookieName: 'CAS_Auth_User', // @TODO, test when i figure out how to set x-domain cookies
});
var wigetData = {
widget: myWidget,
username: 'someun',
password: 'somepassword',
};
testUtils.setWidgetFields(wigetData);
myWidget.login(wigetData)
.then(function() {
t.ok(
jQuery('#api_call_form button').eq(0).text(),
'Log Out',
'login cycle successful'
);
}, t.end)
.then(function() {
testUtils.teardownWidget(myWidget);
t.end();
});
});
test('initial logged in state', function(t) {
t.plan(2);
var authCookieName = 'test_auth_cookie';
var username = 'test_user_name';
var myWidget;
// Fake an initial 'authorized' state by setting the appropriate cookie and
// stored credentials
// TODO: Figure out how to mock/spy on the 'auth' module
cookies.set(authCookieName, 'test_auth_value');
localStorage.COINS_AUTH_CREDENTIALS = JSON.stringify({
id: 'sampleAuthId',
key: 'sampleAuthKey',
username: username,
});
myWidget = testUtils.widgetFactory({
authCookieName: authCookieName,
baseUrl: 'http://localhost:12354',
checkAuth: true,
});
// Hijack widget internals to ensure checks fire at the appropriate time
// TODO: Figure out better way to do this, maybe spies
var originalUpdate = myWidget.update;
myWidget.update = function(newState) {
originalUpdate.call(myWidget, newState);
t.ok(
jQuery(myWidget.element).text().indexOf(username) > 0,
'UI shows username'
);
myWidget.update = originalUpdate;
testUtils.teardownWidget(myWidget);
t.end();
};
myWidget.once('login:success', function(response) {
t.equal(response.username, username, 'retrieves username');
});
});
test('horizontal form', function(t) {
var myWidget = testUtils.widgetFactory({
horizontal: true,
});
var $form = jQuery(myWidget.element).find('form');
t.ok(
$form.attr('class').indexOf('horizontal') !== -1,
'has horizontal class'
);
testUtils.teardownWidget(myWidget);
t.end();
});
test('default messages', function(t) {
var EVENTS = CoinsLogonWidget.EVENTS;
var myWidget = testUtils.widgetFactory();
var offset = '2 days';
var tomorrow = new Date(Date.now() + 36 * 60 * 60 * 1000).toISOString();
myWidget.emit(EVENTS.LOGIN_ACCOUNT_EXPIRED);
t.equal(
testUtils.getNotification(myWidget).text(),
messages.accountExpired,
'Shows account expired message'
);
myWidget.emit(EVENTS.LOGIN_ACCOUNT_WILL_EXPIRE, {
user: {
acctExpDate: tomorrow,
},
});
t.equal(
testUtils.getNotification(myWidget).text(),
messages.accountWillExpire(offset),
'Shows account will expire message'
);
myWidget.emit(EVENTS.LOGIN_PASSWORD_EXPIRED);
t.equal(
testUtils.getNotification(myWidget).text(),
messages.passwordExpired,
'Shows password expired message'
);
myWidget.emit(EVENTS.LOGIN_PASSWORD_WILL_EXPIRE, {
user: {
passwordExpDate: tomorrow,
},
});
t.equal(
testUtils.getNotification(myWidget).text(),
messages.passwordWillExpire(offset),
'Shows password will expire message'
);
testUtils.teardownWidget(myWidget);
t.end();
});
test('custom messages', function(t) {
var EVENTS = CoinsLogonWidget.EVENTS;
var customMessages = {
accountExpired: Math.random().toString(),
accountWillExpire: function(offset) {
return [
'<p>Your account will expire in ' + offset + '.',
'<a href="#">Reset it!</a></p>',
].join(' ');
},
passwordExpired: Math.random().toString(),
passwordWillExpire: function(offset) {
return '<p><span>Your</span> password <b>is</b> <em>gross</em></p>';
},
};
var myWidget = testUtils.widgetFactory({
messages: customMessages,
});
var offset = '2 days';
var tomorrow = new Date(Date.now() + 36 * 60 * 60 * 1000).toISOString();
myWidget.emit(EVENTS.LOGIN_ACCOUNT_EXPIRED);
t.equal(
testUtils.getNotification(myWidget).html(),
customMessages.accountExpired,
'Shows account expired message'
);
myWidget.emit(EVENTS.LOGIN_ACCOUNT_WILL_EXPIRE, {
user: {
acctExpDate: tomorrow,
},
});
t.equal(
testUtils.getNotification(myWidget).html(),
customMessages.accountWillExpire(offset),
'Shows account will expire message'
);
myWidget.emit(EVENTS.LOGIN_PASSWORD_EXPIRED);
t.equal(
testUtils.getNotification(myWidget).html(),
customMessages.passwordExpired,
'Shows password expired message'
);
myWidget.emit(EVENTS.LOGIN_PASSWORD_WILL_EXPIRE, {
user: {
passwordExpDate: tomorrow,
},
});
t.equal(
testUtils.getNotification(myWidget).html(),
customMessages.passwordWillExpire(offset),
'Shows password will expire message'
);
testUtils.teardownWidget(myWidget);
t.end();
});
test('redirect property/button', function(t) {
var redirectUrl = 'http://localhost:1337';
var myWidget = testUtils.widgetFactory({
redirectUrl: redirectUrl,
});
var $widget = jQuery(myWidget.element);
myWidget.update({ isLoggedIn: true });
t.ok(
$widget.find('a.coins-logon-widget-button').length,
'Has redirect link'
);
t.equal(
$widget.find('a.coins-logon-widget-button').attr('href'),
redirectUrl,
'Redirect URL added to link'
);
testUtils.teardownWidget(myWidget);
t.end();
});
/**
* Ensure that the username and password fields' values are persisted when the
* widget re-renders its `form` component.
*/
test('inputs maintain value', function(t) {
var username = 'Test Mc\'Testem';
var password = 'most_secret_password';
var myWidget = testUtils.widgetFactory();
var $widget = jQuery(myWidget.element);
testUtils.setWidgetFields({
password: password,
username: username,
widget: myWidget,
});
myWidget.emit(CoinsLogonWidget.EVENTS.LOGIN_ERROR, 'Invalid credentials');
t.equal(
$widget.find('input[name=username]').val(),
username,
'Username input value maintained'
);
t.equal(
$widget.find('input[name=password]').val(),
password,
'Password input value maintained'
);
t.end();
});