chore(build): Adding jscs validateIndentation rule
Conflicts: app/tests/spec/lib/fxa-client.js
This commit is contained in:
Родитель
ca64752fd3
Коммит
bc2e215047
|
@ -14,6 +14,7 @@
|
|||
"requireSpaceAfterPrefixUnaryOperators": ["~"],
|
||||
"requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
|
||||
"requireSpacesInConditionalExpression": true,
|
||||
"validateIndentation": 2,
|
||||
"validateLineBreaks": "LF",
|
||||
"validateQuoteMarks": true,
|
||||
"validateJSDoc": {
|
|
@ -46,8 +46,6 @@ function (
|
|||
Relier
|
||||
) {
|
||||
|
||||
|
||||
|
||||
function isMetricsCollectionEnabled (sampleRate) {
|
||||
return Math.random() <= sampleRate;
|
||||
}
|
||||
|
@ -76,10 +74,10 @@ function (
|
|||
|
||||
// fetch both config and translations in parallel to speed up load.
|
||||
return p.all([
|
||||
this.initializeConfig(),
|
||||
this.initializeL10n()
|
||||
])
|
||||
.then(_.bind(this.allResourcesReady, this));
|
||||
this.initializeConfig(),
|
||||
this.initializeL10n()
|
||||
])
|
||||
.then(_.bind(this.allResourcesReady, this));
|
||||
},
|
||||
|
||||
initializeConfig: function () {
|
||||
|
|
|
@ -112,45 +112,45 @@ function (_, FxaClient, $, p, Session, AuthErrors, Constants, Channels) {
|
|||
options = options || {};
|
||||
|
||||
return p().then(function() {
|
||||
// If we already verified in signUp that we can link with
|
||||
// the desktop, don't do it again. Otherwise,
|
||||
// make the call over to the Desktop code to ask if
|
||||
// we can allow the linking.
|
||||
if (!options.verifiedCanLinkAccount) {
|
||||
return self._checkForDesktopSyncRelinkWarning(email);
|
||||
}
|
||||
return;
|
||||
})
|
||||
.then(_.bind(self._getClientAsync, self))
|
||||
.then(function (client) {
|
||||
return client.signIn(email, password, { keys: true });
|
||||
})
|
||||
.then(function (accountData) {
|
||||
// get rid of any old data.
|
||||
Session.clear();
|
||||
// If we already verified in signUp that we can link with
|
||||
// the desktop, don't do it again. Otherwise,
|
||||
// make the call over to the Desktop code to ask if
|
||||
// we can allow the linking.
|
||||
if (!options.verifiedCanLinkAccount) {
|
||||
return self._checkForDesktopSyncRelinkWarning(email);
|
||||
}
|
||||
return;
|
||||
})
|
||||
.then(_.bind(self._getClientAsync, self))
|
||||
.then(function (client) {
|
||||
return client.signIn(email, password, { keys: true });
|
||||
})
|
||||
.then(function (accountData) {
|
||||
// get rid of any old data.
|
||||
Session.clear();
|
||||
|
||||
var updatedSessionData = {
|
||||
email: email,
|
||||
uid: accountData.uid,
|
||||
unwrapBKey: accountData.unwrapBKey,
|
||||
keyFetchToken: accountData.keyFetchToken,
|
||||
sessionToken: accountData.sessionToken,
|
||||
sessionTokenContext: Session.context,
|
||||
customizeSync: options.customizeSync
|
||||
};
|
||||
var updatedSessionData = {
|
||||
email: email,
|
||||
uid: accountData.uid,
|
||||
unwrapBKey: accountData.unwrapBKey,
|
||||
keyFetchToken: accountData.keyFetchToken,
|
||||
sessionToken: accountData.sessionToken,
|
||||
sessionTokenContext: Session.context,
|
||||
customizeSync: options.customizeSync
|
||||
};
|
||||
|
||||
Session.set(updatedSessionData);
|
||||
// Skipping the relink warning is only relevant to the channel
|
||||
// communication with the Desktop browser. It may have been
|
||||
// done during a sign up flow.
|
||||
updatedSessionData.verifiedCanLinkAccount = true;
|
||||
Session.set(updatedSessionData);
|
||||
// Skipping the relink warning is only relevant to the channel
|
||||
// communication with the Desktop browser. It may have been
|
||||
// done during a sign up flow.
|
||||
updatedSessionData.verifiedCanLinkAccount = true;
|
||||
|
||||
return Channels.sendExpectResponse('login', updatedSessionData, {
|
||||
channel: self._channel
|
||||
}).then(function () {
|
||||
return accountData;
|
||||
});
|
||||
});
|
||||
return Channels.sendExpectResponse('login', updatedSessionData, {
|
||||
channel: self._channel
|
||||
}).then(function () {
|
||||
return accountData;
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
'use strict';
|
||||
|
||||
require([
|
||||
'./require_config'
|
||||
],
|
||||
function (RequireConfig) {
|
||||
// Ensure config is loaded before trying to load any other scripts.
|
||||
require(['./lib/app-start'], function (AppStart) {
|
||||
var appStart = new AppStart();
|
||||
appStart.startApp();
|
||||
});
|
||||
'./require_config'
|
||||
],
|
||||
function (RequireConfig) {
|
||||
// Ensure config is loaded before trying to load any other scripts.
|
||||
require(['./lib/app-start'], function (AppStart) {
|
||||
var appStart = new AppStart();
|
||||
appStart.startApp();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -54,13 +54,13 @@ function (_, BaseView, FormView, Template, Session, PasswordMixin, FloatingPlace
|
|||
|
||||
var self = this;
|
||||
return this.fxaClient.isPasswordResetComplete(this.token)
|
||||
.then(function (isComplete) {
|
||||
self._isLinkExpired = isComplete;
|
||||
if (isComplete) {
|
||||
self.logEvent('complete_reset_password:link_expired');
|
||||
}
|
||||
return true;
|
||||
});
|
||||
.then(function (isComplete) {
|
||||
self._isLinkExpired = isComplete;
|
||||
if (isComplete) {
|
||||
self.logEvent('complete_reset_password:link_expired');
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
|
||||
afterRender: function() {
|
||||
|
|
|
@ -52,12 +52,12 @@ define([
|
|||
}
|
||||
|
||||
return Channels.sendExpectResponse(message, data, {
|
||||
window: self.window,
|
||||
channel: self.channel
|
||||
}).then(null, function (err) {
|
||||
self.clearTimeout(self._expectResponseTimeout);
|
||||
throw err;
|
||||
});
|
||||
window: self.window,
|
||||
channel: self.channel
|
||||
}).then(null, function (err) {
|
||||
self.clearTimeout(self._expectResponseTimeout);
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -151,9 +151,9 @@ define([
|
|||
|
||||
finishOAuthFlowDifferentBrowser: function () {
|
||||
return _notifyChannel.call(this, 'oauth_complete', {
|
||||
redirect: this.serviceRedirectURI,
|
||||
error: RP_DIFFERENT_BROWSER_ERROR_CODE
|
||||
});
|
||||
redirect: this.serviceRedirectURI,
|
||||
error: RP_DIFFERENT_BROWSER_ERROR_CODE
|
||||
});
|
||||
},
|
||||
|
||||
finishOAuthFlow: buttonProgressIndicator(function (viewOptions) {
|
||||
|
|
|
@ -23,9 +23,9 @@ function (_, p, SignInView, ServiceMixin) {
|
|||
beforeRender: function() {
|
||||
var self = this;
|
||||
return p().then(function () {
|
||||
return SignInView.prototype.beforeRender.call(self);
|
||||
})
|
||||
.then(_.bind(this.setServiceInfo, this));
|
||||
return SignInView.prototype.beforeRender.call(self);
|
||||
})
|
||||
.then(_.bind(this.setServiceInfo, this));
|
||||
},
|
||||
|
||||
afterRender: function() {
|
||||
|
|
|
@ -31,9 +31,9 @@ function (_, p, BaseView, SignUpView, ServiceMixin) {
|
|||
beforeRender: function() {
|
||||
var self = this;
|
||||
return p().then(function () {
|
||||
return SignUpView.prototype.beforeRender.call(self);
|
||||
})
|
||||
.then(_.bind(this.setServiceInfo, this));
|
||||
return SignUpView.prototype.beforeRender.call(self);
|
||||
})
|
||||
.then(_.bind(this.setServiceInfo, this));
|
||||
},
|
||||
|
||||
afterRender: function() {
|
||||
|
|
|
@ -5,111 +5,111 @@
|
|||
'use strict';
|
||||
|
||||
define([
|
||||
'jquery',
|
||||
'underscore',
|
||||
'views/form',
|
||||
'stache!templates/settings/avatar_change',
|
||||
'lib/session',
|
||||
'lib/auth-errors'
|
||||
],
|
||||
function ($, _, FormView, Template, Session, AuthErrors) {
|
||||
'jquery',
|
||||
'underscore',
|
||||
'views/form',
|
||||
'stache!templates/settings/avatar_change',
|
||||
'lib/session',
|
||||
'lib/auth-errors'
|
||||
],
|
||||
function ($, _, FormView, Template, Session, AuthErrors) {
|
||||
|
||||
// a blank 1x1 png
|
||||
var pngSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==';
|
||||
// a blank 1x1 png
|
||||
var pngSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==';
|
||||
|
||||
var View = FormView.extend({
|
||||
// user must be authenticated to see Settings
|
||||
mustAuth: true,
|
||||
var View = FormView.extend({
|
||||
// user must be authenticated to see Settings
|
||||
mustAuth: true,
|
||||
|
||||
template: Template,
|
||||
className: 'avatar_change',
|
||||
template: Template,
|
||||
className: 'avatar_change',
|
||||
|
||||
events: {
|
||||
'click #file': 'filePicker',
|
||||
'click .remove': 'remove',
|
||||
'change #imageLoader': 'fileSet'
|
||||
},
|
||||
events: {
|
||||
'click #file': 'filePicker',
|
||||
'click .remove': 'remove',
|
||||
'change #imageLoader': 'fileSet'
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
Session.clear('cropImgWidth');
|
||||
Session.clear('cropImgHeight');
|
||||
// override in tests
|
||||
this.FileReader = FileReader;
|
||||
},
|
||||
initialize: function () {
|
||||
Session.clear('cropImgWidth');
|
||||
Session.clear('cropImgHeight');
|
||||
// override in tests
|
||||
this.FileReader = FileReader;
|
||||
},
|
||||
|
||||
afterRender: function () {
|
||||
var wrapper = $('<div/>').css({ height: 0, width: 0, 'overflow': 'hidden' });
|
||||
this.$(':file').wrap(wrapper);
|
||||
},
|
||||
afterRender: function () {
|
||||
var wrapper = $('<div/>').css({ height: 0, width: 0, 'overflow': 'hidden' });
|
||||
this.$(':file').wrap(wrapper);
|
||||
},
|
||||
|
||||
context: function () {
|
||||
return {
|
||||
avatar: Session.avatar
|
||||
};
|
||||
},
|
||||
context: function () {
|
||||
return {
|
||||
avatar: Session.avatar
|
||||
};
|
||||
},
|
||||
|
||||
remove: function () {
|
||||
Session.clear('avatar');
|
||||
this.navigate('settings/avatar');
|
||||
},
|
||||
remove: function () {
|
||||
Session.clear('avatar');
|
||||
this.navigate('settings/avatar');
|
||||
},
|
||||
|
||||
filePicker: function () {
|
||||
// skip the file picker if this is an automater browser
|
||||
if (this.automatedBrowser) {
|
||||
var self = this;
|
||||
require(['draggable', 'touch-punch'], function () {
|
||||
Session.set('cropImgSrc', pngSrc);
|
||||
Session.set('cropImgWidth', 1);
|
||||
Session.set('cropImgHeight', 1);
|
||||
|
||||
self.navigate('settings/avatar/crop');
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.$('#imageLoader').click();
|
||||
},
|
||||
|
||||
fileSet: function (e) {
|
||||
filePicker: function () {
|
||||
// skip the file picker if this is an automater browser
|
||||
if (this.automatedBrowser) {
|
||||
var self = this;
|
||||
var file = e.target.files[0];
|
||||
require(['draggable', 'touch-punch'], function () {
|
||||
Session.set('cropImgSrc', pngSrc);
|
||||
Session.set('cropImgWidth', 1);
|
||||
Session.set('cropImgHeight', 1);
|
||||
|
||||
// Define our callbacks here to avoid a circular DOM reference
|
||||
var imgOnload = function () {
|
||||
// Store the width and height for the cropper view
|
||||
Session.set('cropImgWidth', this.width);
|
||||
Session.set('cropImgHeight', this.height);
|
||||
require(['draggable', 'touch-punch'], function () {
|
||||
self.navigate('settings/avatar/crop');
|
||||
});
|
||||
};
|
||||
|
||||
var imgOnerrer = function () {
|
||||
self.navigate('settings/avatar', {
|
||||
error: AuthErrors.toMessage('UNUSABLE_IMAGE')
|
||||
});
|
||||
};
|
||||
|
||||
if (file.type.match('image.*')) {
|
||||
var reader = new self.FileReader();
|
||||
|
||||
reader.onload = function (event) {
|
||||
var src = event.target.result;
|
||||
|
||||
Session.set('cropImgSrc', src);
|
||||
|
||||
var img = new Image();
|
||||
img.src = src;
|
||||
img.onload = imgOnload;
|
||||
img.onerror = imgOnerrer;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
} else {
|
||||
self.navigate('settings/avatar', {
|
||||
error: AuthErrors.toMessage('UNUSABLE_IMAGE')
|
||||
});
|
||||
}
|
||||
self.navigate('settings/avatar/crop');
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
this.$('#imageLoader').click();
|
||||
},
|
||||
|
||||
return View;
|
||||
fileSet: function (e) {
|
||||
var self = this;
|
||||
var file = e.target.files[0];
|
||||
|
||||
// Define our callbacks here to avoid a circular DOM reference
|
||||
var imgOnload = function () {
|
||||
// Store the width and height for the cropper view
|
||||
Session.set('cropImgWidth', this.width);
|
||||
Session.set('cropImgHeight', this.height);
|
||||
require(['draggable', 'touch-punch'], function () {
|
||||
self.navigate('settings/avatar/crop');
|
||||
});
|
||||
};
|
||||
|
||||
var imgOnerrer = function () {
|
||||
self.navigate('settings/avatar', {
|
||||
error: AuthErrors.toMessage('UNUSABLE_IMAGE')
|
||||
});
|
||||
};
|
||||
|
||||
if (file.type.match('image.*')) {
|
||||
var reader = new self.FileReader();
|
||||
|
||||
reader.onload = function (event) {
|
||||
var src = event.target.result;
|
||||
|
||||
Session.set('cropImgSrc', src);
|
||||
|
||||
var img = new Image();
|
||||
img.src = src;
|
||||
img.onload = imgOnload;
|
||||
img.onerror = imgOnerrer;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
} else {
|
||||
self.navigate('settings/avatar', {
|
||||
error: AuthErrors.toMessage('UNUSABLE_IMAGE')
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return View;
|
||||
});
|
||||
|
|
|
@ -66,13 +66,13 @@ function (_, p, BaseView, FormView, SignInTemplate, Constants, Session, Password
|
|||
beforeRender: function() {
|
||||
var self = this;
|
||||
return p().then(function () {
|
||||
return FormView.prototype.beforeRender.call(self);
|
||||
})
|
||||
.then(function () {
|
||||
if (self.hasService() && self.isSync()) {
|
||||
return self.setServiceInfo();
|
||||
}
|
||||
});
|
||||
return FormView.prototype.beforeRender.call(self);
|
||||
})
|
||||
.then(function () {
|
||||
if (self.hasService() && self.isSync()) {
|
||||
return self.setServiceInfo();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
submit: function () {
|
||||
|
|
|
@ -67,13 +67,13 @@ function (_, p, BaseView, FormView, Template, Session, PasswordMixin, AuthErrors
|
|||
|
||||
var self = this;
|
||||
return p().then(function () {
|
||||
return FormView.prototype.beforeRender.call(self);
|
||||
})
|
||||
.then(function () {
|
||||
if (self.hasService() && self.isSync()) {
|
||||
return self.setServiceInfo();
|
||||
}
|
||||
});
|
||||
return FormView.prototype.beforeRender.call(self);
|
||||
})
|
||||
.then(function () {
|
||||
if (self.hasService() && self.isSync()) {
|
||||
return self.setServiceInfo();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// afterRender fucnction to handle select-row hack (issue 822)
|
||||
|
@ -189,30 +189,30 @@ function (_, p, BaseView, FormView, Template, Session, PasswordMixin, AuthErrors
|
|||
|
||||
var self = this;
|
||||
return this.fxaClient.signUp(email, password, {
|
||||
customizeSync: customizeSync,
|
||||
preVerifyToken: preVerifyToken
|
||||
}).then(_.bind(self.onSignUpSuccess, self))
|
||||
.then(null, function (err) {
|
||||
// Account already exists. No attempt is made at signing the
|
||||
// user in directly, instead, point the user to the signin page
|
||||
// where the entered email/password will be prefilled.
|
||||
if (AuthErrors.is(err, 'ACCOUNT_ALREADY_EXISTS')) {
|
||||
return self._suggestSignIn(err);
|
||||
} else if (AuthErrors.is(err, 'USER_CANCELED_LOGIN')) {
|
||||
self.logEvent('login:canceled');
|
||||
// if user canceled login, just stop
|
||||
return;
|
||||
} else if (self._preVerifyToken && AuthErrors.is(err, 'INVALID_VERIFICATION_CODE')) {
|
||||
// The token was invalid and the auth server could not pre-verify
|
||||
// the user. Now, just create a new user and force them to verify
|
||||
// their email.
|
||||
self._preVerifyToken = null;
|
||||
return self._createAccount();
|
||||
}
|
||||
customizeSync: customizeSync,
|
||||
preVerifyToken: preVerifyToken
|
||||
}).then(_.bind(self.onSignUpSuccess, self))
|
||||
.then(null, function (err) {
|
||||
// Account already exists. No attempt is made at signing the
|
||||
// user in directly, instead, point the user to the signin page
|
||||
// where the entered email/password will be prefilled.
|
||||
if (AuthErrors.is(err, 'ACCOUNT_ALREADY_EXISTS')) {
|
||||
return self._suggestSignIn(err);
|
||||
} else if (AuthErrors.is(err, 'USER_CANCELED_LOGIN')) {
|
||||
self.logEvent('login:canceled');
|
||||
// if user canceled login, just stop
|
||||
return;
|
||||
} else if (self._preVerifyToken && AuthErrors.is(err, 'INVALID_VERIFICATION_CODE')) {
|
||||
// The token was invalid and the auth server could not pre-verify
|
||||
// the user. Now, just create a new user and force them to verify
|
||||
// their email.
|
||||
self._preVerifyToken = null;
|
||||
return self._createAccount();
|
||||
}
|
||||
|
||||
// re-throw error, it will be handled at a lower level.
|
||||
throw err;
|
||||
});
|
||||
// re-throw error, it will be handled at a lower level.
|
||||
throw err;
|
||||
});
|
||||
},
|
||||
|
||||
onSignUpSuccess: function(accountData) {
|
||||
|
|
|
@ -112,9 +112,9 @@ function (chai, AuthErrors) {
|
|||
describe('is', function () {
|
||||
it('checks if an error returned from the server is of a given type',
|
||||
function () {
|
||||
assert.isTrue(AuthErrors.is({ errno: 102 }, 'UNKNOWN_ACCOUNT'));
|
||||
assert.isFalse(AuthErrors.is({ errno: 103 }, 'UNKNOWN_ACCOUNT'));
|
||||
});
|
||||
assert.isTrue(AuthErrors.is({ errno: 102 }, 'UNKNOWN_ACCOUNT'));
|
||||
assert.isFalse(AuthErrors.is({ errno: 103 }, 'UNKNOWN_ACCOUNT'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -75,12 +75,12 @@ function (chai, WindowMock, Session, FxDesktopChannel, TestHelpers) {
|
|||
it('registers a callback to be called when the browser sends ' +
|
||||
'the registered message', function (done) {
|
||||
|
||||
channel.on('call-the-callback', function () {
|
||||
done();
|
||||
});
|
||||
channel.on('call-the-callback', function () {
|
||||
done();
|
||||
});
|
||||
|
||||
dispatchEvent('call-the-callback');
|
||||
});
|
||||
dispatchEvent('call-the-callback');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,64 +6,63 @@
|
|||
|
||||
|
||||
define([
|
||||
'underscore',
|
||||
'chai',
|
||||
'router',
|
||||
'views/sign_in',
|
||||
'lib/channels/web',
|
||||
'/tests/mocks/window.js'
|
||||
],
|
||||
function (_, chai, Router, View, WebChannel, WindowMock) {
|
||||
var assert = chai.assert;
|
||||
'underscore',
|
||||
'chai',
|
||||
'router',
|
||||
'views/sign_in',
|
||||
'lib/channels/web',
|
||||
'/tests/mocks/window.js'
|
||||
],
|
||||
function (_, chai, Router, View, WebChannel, WindowMock) {
|
||||
var assert = chai.assert;
|
||||
|
||||
describe('lib/channel/web', function () {
|
||||
it('requires an id', function (done) {
|
||||
try {
|
||||
new WebChannel();
|
||||
} catch (e) {
|
||||
assert.equal(e.message, 'WebChannel must have an id');
|
||||
done();
|
||||
}
|
||||
describe('lib/channel/web', function () {
|
||||
it('requires an id', function (done) {
|
||||
try {
|
||||
new WebChannel();
|
||||
} catch (e) {
|
||||
assert.equal(e.message, 'WebChannel must have an id');
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
describe('send', function () {
|
||||
var windowMock;
|
||||
var channel;
|
||||
|
||||
beforeEach(function () {
|
||||
windowMock = new WindowMock();
|
||||
});
|
||||
|
||||
describe('send', function () {
|
||||
var windowMock;
|
||||
var channel;
|
||||
|
||||
beforeEach(function () {
|
||||
windowMock = new WindowMock();
|
||||
it('sends an event with a callback', function (done) {
|
||||
channel = new WebChannel('MyChannel', windowMock);
|
||||
channel.init({
|
||||
window: windowMock
|
||||
});
|
||||
|
||||
it('sends an event with a callback', function (done) {
|
||||
channel = new WebChannel('MyChannel', windowMock);
|
||||
channel.init({
|
||||
window: windowMock
|
||||
});
|
||||
channel.send('after_render', {}, function (err, response) {
|
||||
assert.notOk(err);
|
||||
assert.ok(windowMock.dispatchedEvents['after_render']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
channel.send('after_render', {}, function (err, response) {
|
||||
assert.notOk(err);
|
||||
assert.ok(windowMock.dispatchedEvents['after_render']);
|
||||
done();
|
||||
});
|
||||
it('throws an error if dispatchEvent fails', function (done) {
|
||||
windowMock.dispatchEvent = function () {
|
||||
throw new Error('Not supported');
|
||||
};
|
||||
|
||||
channel = new WebChannel('MyChannel', windowMock);
|
||||
channel.init({
|
||||
window: windowMock
|
||||
});
|
||||
|
||||
it('throws an error if dispatchEvent fails', function (done) {
|
||||
windowMock.dispatchEvent = function () {
|
||||
throw new Error('Not supported');
|
||||
};
|
||||
|
||||
channel = new WebChannel('MyChannel', windowMock);
|
||||
channel.init({
|
||||
window: windowMock
|
||||
});
|
||||
|
||||
channel.send('after_render', {}, function (err, response) {
|
||||
assert.equal(err.message, 'Not supported');
|
||||
assert.notOk(response);
|
||||
done();
|
||||
}
|
||||
);
|
||||
channel.send('after_render', {}, function (err, response) {
|
||||
assert.equal(err.message, 'Not supported');
|
||||
assert.notOk(response);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -155,7 +155,7 @@ function (chai, $, sinon, p, ChannelMock, testHelpers,
|
|||
});
|
||||
|
||||
it('signUp existing unverified user with different password signs ' +
|
||||
'user up again', function () {
|
||||
'user up again', function () {
|
||||
return client.signUp(email, password)
|
||||
.then(function () {
|
||||
return client.signUp(email, 'different_password');
|
||||
|
@ -182,15 +182,15 @@ function (chai, $, sinon, p, ChannelMock, testHelpers,
|
|||
});
|
||||
|
||||
return client.signUp(email, password, {
|
||||
preVerifyToken: preVerifyToken
|
||||
})
|
||||
.then(function () {
|
||||
assert.isTrue(realClient.signUp.calledWith(trim(email), password, {
|
||||
preVerifyToken: preVerifyToken,
|
||||
keys: true
|
||||
}));
|
||||
assert.isTrue(realClient.signIn.called);
|
||||
});
|
||||
preVerifyToken: preVerifyToken
|
||||
})
|
||||
.then(function () {
|
||||
assert.isTrue(realClient.signUp.calledWith(trim(email), password, {
|
||||
preVerifyToken: preVerifyToken,
|
||||
keys: true
|
||||
}));
|
||||
assert.isTrue(realClient.signIn.called);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ function (chai, $, testHelpers, sinon,
|
|||
|
||||
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{ "redirect": "' + redirect + '" }']);
|
||||
'{ "redirect": "' + redirect + '" }']);
|
||||
|
||||
return client.getCode(params)
|
||||
.then(function (result) {
|
||||
|
@ -93,127 +93,125 @@ function (chai, $, testHelpers, sinon,
|
|||
})]);
|
||||
|
||||
|
||||
return client.getCode(params)
|
||||
.then(function (result) {
|
||||
assert.fail('unexpected success');
|
||||
}, function (err) {
|
||||
assert.isTrue(OAuthErrors.is(err, 'INCORRECT_REDIRECT'));
|
||||
return client.getCode(params)
|
||||
.then(function (result) {
|
||||
assert.fail('unexpected success');
|
||||
}, function (err) {
|
||||
assert.isTrue(OAuthErrors.is(err, 'INCORRECT_REDIRECT'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getClientInfo', function () {
|
||||
var clientId = 'clientId';
|
||||
describe('getClientInfo', function () {
|
||||
var clientId = 'clientId';
|
||||
|
||||
it('normally response with a name and imageUri', function () {
|
||||
server.respondWith('GET', OAUTH_URL + '/v1/client/' + clientId,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
it('normally response with a name and imageUri', function () {
|
||||
server.respondWith('GET', OAUTH_URL + '/v1/client/' + clientId,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{ "name": "MozRP", "imageUri": "https://mozilla.org/firefox.png" }']);
|
||||
|
||||
return client.getClientInfo(clientId)
|
||||
.then(function (result) {
|
||||
assert.ok(result);
|
||||
assert.equal(result.name, 'MozRP');
|
||||
return client.getClientInfo(clientId)
|
||||
.then(function (result) {
|
||||
assert.ok(result);
|
||||
assert.equal(result.name, 'MozRP');
|
||||
});
|
||||
});
|
||||
|
||||
it('responds with a SERVICE_UNAVAILABLE error if the service is unavailable', function () {
|
||||
var clientId = 'clientId';
|
||||
|
||||
server.respondWith('GET', OAUTH_URL + '/v1/client/' + clientId,
|
||||
[0, {}, '']);
|
||||
|
||||
return client.getClientInfo(clientId)
|
||||
.then(function (result) {
|
||||
assert.fail('unexpected success');
|
||||
}, function (err) {
|
||||
assert.isTrue(OAuthErrors.is(err, 'SERVICE_UNAVAILABLE'));
|
||||
});
|
||||
});
|
||||
|
||||
it('converts returned errors to OAuth error objects', function () {
|
||||
var clientId = 'clientId';
|
||||
|
||||
server.respondWith('GET', OAUTH_URL + '/v1/client/' + clientId,
|
||||
[400, { 'Content-Type': 'application/json' },
|
||||
JSON.stringify({
|
||||
errno: OAuthErrors.toCode('EXPIRED_CODE'),
|
||||
code: 400
|
||||
})]);
|
||||
|
||||
return client.getClientInfo(clientId)
|
||||
.then(function (result) {
|
||||
assert.fail('unexpected success');
|
||||
}, function (err) {
|
||||
assert.isTrue(OAuthErrors.is(err, 'EXPIRED_CODE'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getToken', function () {
|
||||
it('normally responds with a token', function () {
|
||||
var token = 'access token';
|
||||
|
||||
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{ "scope": "profile", "token_type": "bearer", "access_token": "' + token + '" }']);
|
||||
|
||||
var params = {
|
||||
assertion: 'assertion',
|
||||
client_id: 'deadbeef',
|
||||
scope: 'profile'
|
||||
};
|
||||
|
||||
return client.getToken(params)
|
||||
.then(function (result) {
|
||||
assert.ok(result);
|
||||
assert.equal(result.access_token, 'access token');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('responds with a SERVICE_UNAVAILABLE error if the service is unavailable', function () {
|
||||
var clientId = 'clientId';
|
||||
it('responds with a SERVICE_UNAVAILABLE error if the service is unavailable', function () {
|
||||
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
|
||||
[0, {}, '']);
|
||||
|
||||
server.respondWith('GET', OAUTH_URL + '/v1/client/' + clientId,
|
||||
[0, {}, '']);
|
||||
var params = {
|
||||
assertion: 'assertion',
|
||||
client_id: 'deadbeef',
|
||||
scope: 'profile'
|
||||
};
|
||||
|
||||
return client.getClientInfo(clientId)
|
||||
.then(function (result) {
|
||||
assert.fail('unexpected success');
|
||||
}, function (err) {
|
||||
assert.isTrue(OAuthErrors.is(err, 'SERVICE_UNAVAILABLE'));
|
||||
return client.getToken(params)
|
||||
.then(function (result) {
|
||||
assert.fail('unexpected success');
|
||||
}, function (err) {
|
||||
assert.isTrue(OAuthErrors.is(err, 'SERVICE_UNAVAILABLE'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('converts returned errors to OAuth error objects', function () {
|
||||
var clientId = 'clientId';
|
||||
it('converts returned errors to OAuth error objects', function () {
|
||||
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
|
||||
[400, { 'Content-Type': 'application/json' },
|
||||
JSON.stringify({
|
||||
errno: OAuthErrors.toCode('INVALID_ASSERTION'),
|
||||
code: 400
|
||||
})]);
|
||||
|
||||
server.respondWith('GET', OAUTH_URL + '/v1/client/' + clientId,
|
||||
[400, { 'Content-Type': 'application/json' },
|
||||
JSON.stringify({
|
||||
errno: OAuthErrors.toCode('EXPIRED_CODE'),
|
||||
code: 400
|
||||
})]);
|
||||
var params = {
|
||||
assertion: 'assertion',
|
||||
client_id: 'deadbeef',
|
||||
scope: 'profile'
|
||||
};
|
||||
|
||||
|
||||
return client.getClientInfo(clientId)
|
||||
.then(function (result) {
|
||||
assert.fail('unexpected success');
|
||||
}, function (err) {
|
||||
assert.isTrue(OAuthErrors.is(err, 'EXPIRED_CODE'));
|
||||
return client.getToken(params)
|
||||
.then(function (result) {
|
||||
assert.fail('unexpected success');
|
||||
}, function (err) {
|
||||
assert.isTrue(OAuthErrors.is(err, 'INVALID_ASSERTION'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('getToken', function () {
|
||||
it('normally responds with a token', function () {
|
||||
var token = 'access token';
|
||||
|
||||
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{ "scope": "profile", "token_type": "bearer", "access_token": "' + token + '" }']);
|
||||
|
||||
var params = {
|
||||
assertion: 'assertion',
|
||||
client_id: 'deadbeef',
|
||||
scope: 'profile'
|
||||
};
|
||||
|
||||
return client.getToken(params)
|
||||
.then(function (result) {
|
||||
assert.ok(result);
|
||||
assert.equal(result.access_token, 'access token');
|
||||
});
|
||||
});
|
||||
|
||||
it('responds with a SERVICE_UNAVAILABLE error if the service is unavailable', function () {
|
||||
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
|
||||
[0, {}, '']);
|
||||
|
||||
var params = {
|
||||
assertion: 'assertion',
|
||||
client_id: 'deadbeef',
|
||||
scope: 'profile'
|
||||
};
|
||||
|
||||
return client.getToken(params)
|
||||
.then(function (result) {
|
||||
assert.fail('unexpected success');
|
||||
}, function (err) {
|
||||
assert.isTrue(OAuthErrors.is(err, 'SERVICE_UNAVAILABLE'));
|
||||
});
|
||||
});
|
||||
|
||||
it('converts returned errors to OAuth error objects', function () {
|
||||
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
|
||||
[400, { 'Content-Type': 'application/json' },
|
||||
JSON.stringify({
|
||||
errno: OAuthErrors.toCode('INVALID_ASSERTION'),
|
||||
code: 400
|
||||
})]);
|
||||
|
||||
var params = {
|
||||
assertion: 'assertion',
|
||||
client_id: 'deadbeef',
|
||||
scope: 'profile'
|
||||
};
|
||||
|
||||
return client.getToken(params)
|
||||
.then(function (result) {
|
||||
assert.fail('unexpected success');
|
||||
}, function (err) {
|
||||
assert.isTrue(OAuthErrors.is(err, 'INVALID_ASSERTION'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -56,8 +56,8 @@ function (chai, OAuthErrors) {
|
|||
describe('is', function () {
|
||||
it('checks if an error returned from the server is of a given type',
|
||||
function () {
|
||||
assert.isTrue(OAuthErrors.is({ errno: 101 }, 'UNKNOWN_CLIENT'));
|
||||
});
|
||||
assert.isTrue(OAuthErrors.is({ errno: 101 }, 'UNKNOWN_CLIENT'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -50,7 +50,7 @@ function (chai, $, sinon,
|
|||
it('normally responds with profile', function () {
|
||||
server.respondWith('GET', PROFILE_URL + '/v1/profile',
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{ "uid": "' + UID + '", "email": "' + EMAIL + '" }']);
|
||||
'{ "uid": "' + UID + '", "email": "' + EMAIL + '" }']);
|
||||
|
||||
return client.getProfile()
|
||||
.then(function (result) {
|
||||
|
@ -80,31 +80,31 @@ function (chai, $, sinon,
|
|||
code: 403
|
||||
})]);
|
||||
|
||||
return client.getProfile()
|
||||
.then(function (result) {
|
||||
assert.fail('unexpected success');
|
||||
}, function (err) {
|
||||
assert.isTrue(ProfileClient.Errors.is(err, 'UNAUTHORIZED'));
|
||||
return client.getProfile()
|
||||
.then(function (result) {
|
||||
assert.fail('unexpected success');
|
||||
}, function (err) {
|
||||
assert.isTrue(ProfileClient.Errors.is(err, 'UNAUTHORIZED'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getRemoteImage', function () {
|
||||
it('normally responds with remote image', function () {
|
||||
var src = encodeURIComponent('http://example.com/logo.jpg');
|
||||
server.respondWith('GET', PROFILE_URL + '/v1/remote_image/' + src,
|
||||
[200, { 'Content-Type': 'text/plain' },
|
||||
describe('getRemoteImage', function () {
|
||||
it('normally responds with remote image', function () {
|
||||
var src = encodeURIComponent('http://example.com/logo.jpg');
|
||||
server.respondWith('GET', PROFILE_URL + '/v1/remote_image/' + src,
|
||||
[200, { 'Content-Type': 'text/plain' },
|
||||
'data:image/jpeg;base64,ohhai']);
|
||||
|
||||
return client.getRemoteImage('http://example.com/logo.jpg')
|
||||
.then(function (result) {
|
||||
assert.equal(result, 'data:image/jpeg;base64,ohhai');
|
||||
});
|
||||
return client.getRemoteImage('http://example.com/logo.jpg')
|
||||
.then(function (result) {
|
||||
assert.equal(result, 'data:image/jpeg;base64,ohhai');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -64,11 +64,11 @@ function (chai, _, Backbone, Router, SignInView, SignUpView, ReadyView, Session,
|
|||
|
||||
it('preserves window search parameters across screen transition',
|
||||
function () {
|
||||
windowMock.location.search = '?context=' + Constants.FX_DESKTOP_CONTEXT;
|
||||
router.navigate('/forgot');
|
||||
assert.equal(navigateUrl, '/forgot?context=' + Constants.FX_DESKTOP_CONTEXT);
|
||||
assert.deepEqual(navigateOptions, { trigger: true });
|
||||
});
|
||||
windowMock.location.search = '?context=' + Constants.FX_DESKTOP_CONTEXT;
|
||||
router.navigate('/forgot');
|
||||
assert.equal(navigateUrl, '/forgot?context=' + Constants.FX_DESKTOP_CONTEXT);
|
||||
assert.deepEqual(navigateOptions, { trigger: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe('redirectToSignupOrSettings', function () {
|
||||
|
|
|
@ -21,11 +21,11 @@ function (chai, Translator) {
|
|||
[null, '⊥ɥǝɹǝ ʍɐs ɐ dɹoqʅǝɯ ʍıʇɥ ʎonɹ sıƃund ʅıuʞ˙ Hɐs ʇɥıs ɐppɹǝss ɐʅɹǝɐpʎ qǝǝu ɹǝƃısʇǝɹǝp¿'],
|
||||
|
||||
'Error encountered trying to register: %(email)s.': [null,
|
||||
'Ǝɹɹoɹ ǝuɔonuʇǝɹǝp ʇɹʎıuƃ ʇo ɹǝƃısʇɹɐʇıou: %(email)s˙'],
|
||||
'Ǝɹɹoɹ ǝuɔonuʇǝɹǝp ʇɹʎıuƃ ʇo ɹǝƃısʇɹɐʇıou: %(email)s˙'],
|
||||
|
||||
// use one direct translation to prepare for simpler json files.
|
||||
'%s, Persona requires cookies to remember you.':
|
||||
'%s, Ԁǝɹsouɐ ɹǝbnıɹǝs ɔooʞıǝs ʇo ɹǝɯǝɯqǝɹ ʎon˙'
|
||||
'%s, Ԁǝɹsouɐ ɹǝbnıɹǝs ɔooʞıǝs ʇo ɹǝɯǝɯqǝɹ ʎon˙'
|
||||
};
|
||||
|
||||
describe('lib/translator', function () {
|
||||
|
|
|
@ -17,8 +17,8 @@ function (chai, _, Url) {
|
|||
describe('searchParam', function () {
|
||||
it('returns a parameter from window.location.search, if it exists',
|
||||
function() {
|
||||
assert.equal(Url.searchParam('color', '?color=green'), 'green');
|
||||
});
|
||||
assert.equal(Url.searchParam('color', '?color=green'), 'green');
|
||||
});
|
||||
|
||||
it('returns undefined if parameter does not exist', function() {
|
||||
assert.isUndefined(Url.searchParam('animal', '?color=green'));
|
||||
|
@ -34,18 +34,18 @@ function (chai, _, Url) {
|
|||
|
||||
it('returns all parameters from window.location.search, if no whitelist specified',
|
||||
function() {
|
||||
var params = Url.searchParams(search);
|
||||
assert.equal(params.color, 'green');
|
||||
assert.equal(params.email, 'testuser@testuser.com');
|
||||
});
|
||||
var params = Url.searchParams(search);
|
||||
assert.equal(params.color, 'green');
|
||||
assert.equal(params.email, 'testuser@testuser.com');
|
||||
});
|
||||
|
||||
it('only returns whitelisted parameters from window.location.search, if whitelist specified',
|
||||
function() {
|
||||
var params = Url.searchParams(search, ['color', 'notDefined']);
|
||||
assert.equal(params.color, 'green');
|
||||
assert.isFalse('email' in params);
|
||||
assert.isFalse('notDefined' in params);
|
||||
});
|
||||
var params = Url.searchParams(search, ['color', 'notDefined']);
|
||||
assert.equal(params.color, 'green');
|
||||
assert.isFalse('email' in params);
|
||||
assert.isFalse('notDefined' in params);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ function (chai, _, $, AuthErrors, FxaClient, View, RouterMock, TestHelpers, Sess
|
|||
});
|
||||
});
|
||||
|
||||
it('changes from old to new password, keeps sessionTokenContext', function () {
|
||||
it('changes from old to new password, keeps sessionTokenContext', function () {
|
||||
$('#old_password').val('password');
|
||||
$('#new_password').val('new_password');
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ function (chai, $, View, Session, FxaClient, WindowMock, RouterMock) {
|
|||
it('shows no avatar if Session.avatar is undefined', function (done) {
|
||||
Session.set('forceEmail', 'a@a.com');
|
||||
assert.isNull(view.context().avatar);
|
||||
|
||||
|
||||
return view.render()
|
||||
.then(function () {
|
||||
assert.notOk(view.$('.avatar-view img').length);
|
||||
|
|
|
@ -61,7 +61,7 @@ function (chai, $, View, Session, FxaClient, WindowMock, RouterMock, OAuthServer
|
|||
describe('render', function () {
|
||||
it('displays oAuth client name', function () {
|
||||
return view.render()
|
||||
.then(function () {
|
||||
.then(function () {
|
||||
assert.include($('#fxa-signin-header').text(), CLIENT_NAME);
|
||||
// also make sure link is correct
|
||||
assert.equal($('.sign-up').attr('href'), '/oauth/signup');
|
||||
|
|
|
@ -21,16 +21,16 @@ define([
|
|||
function (chai, _, $, p, sinon, View, RouterMock, Session, Assertion, Constants, AuthErrors) {
|
||||
var assert = chai.assert;
|
||||
// 1x1 jpeg
|
||||
var jpgSrcData = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBA' +
|
||||
'MFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMD' +
|
||||
'AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAABAAEDASIAAhEB' +
|
||||
'AxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQ' +
|
||||
'RBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVF' +
|
||||
'VWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx' +
|
||||
'8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcI' +
|
||||
'CQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChY' +
|
||||
'kNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkp' +
|
||||
'OUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKAP/2Q==';
|
||||
var jpgSrcData = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBA' +
|
||||
'MFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMD' +
|
||||
'AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAABAAEDASIAAhEB' +
|
||||
'AxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQ' +
|
||||
'RBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVF' +
|
||||
'VWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx' +
|
||||
'8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcI' +
|
||||
'CQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChY' +
|
||||
'kNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkp' +
|
||||
'OUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKAP/2Q==';
|
||||
|
||||
// These URLs don't depend on our actual configuration; the servers are mocked out.
|
||||
var PROFILE_URL = 'http://127.0.0.1:1111';
|
||||
|
@ -104,8 +104,7 @@ var jpgSrcData = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAw
|
|||
|
||||
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{ "scope": "profile", "token_type": "bearer", "access_token": "token" }']);
|
||||
|
||||
'{ "scope": "profile", "token_type": "bearer", "access_token": "token" }']);
|
||||
|
||||
Assertion.generate = function () {
|
||||
return p('assertion');
|
||||
|
@ -126,51 +125,50 @@ var jpgSrcData = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAw
|
|||
|
||||
server.respondWith('GET', PROFILE_URL + '/v1/remote_image/' + src,
|
||||
[200, { 'Content-Type': 'text/plain' },
|
||||
'data:image/jpeg;base64,']);
|
||||
'data:image/jpeg;base64,']);
|
||||
|
||||
view.render()
|
||||
.then(function () {
|
||||
view.router.on('navigate', function () {
|
||||
try {
|
||||
assert.equal(routerMock.page, 'settings/avatar');
|
||||
assert.equal(view.ephemeralMessages.get('error'), AuthErrors.toMessage('UNUSABLE_IMAGE'));
|
||||
done();
|
||||
} catch (e) {
|
||||
return done(e);
|
||||
}
|
||||
});
|
||||
view.render()
|
||||
.then(function () {
|
||||
view.router.on('navigate', function () {
|
||||
try {
|
||||
assert.equal(routerMock.page, 'settings/avatar');
|
||||
assert.equal(view.ephemeralMessages.get('error'), AuthErrors.toMessage('UNUSABLE_IMAGE'));
|
||||
done();
|
||||
} catch (e) {
|
||||
return done(e);
|
||||
}
|
||||
});
|
||||
|
||||
view.$('.url').val('http://example.com/logo.jpg');
|
||||
view.submit();
|
||||
})
|
||||
.fail(done);
|
||||
view.$('.url').val('http://example.com/logo.jpg');
|
||||
view.submit();
|
||||
})
|
||||
.fail(done);
|
||||
});
|
||||
|
||||
it('submits', function (done) {
|
||||
var src = encodeURIComponent('http://example.com/logo.jpg');
|
||||
|
||||
server.respondWith('GET', PROFILE_URL + '/v1/remote_image/' + src,
|
||||
[200, { 'Content-Type': 'text/plain' },
|
||||
jpgSrcData]);
|
||||
[200, { 'Content-Type': 'text/plain' }, jpgSrcData]);
|
||||
|
||||
view.render()
|
||||
.then(function () {
|
||||
view.router.on('navigate', function () {
|
||||
try {
|
||||
assert.equal(routerMock.page, 'settings/avatar/crop');
|
||||
assert.include(Session.cropImgSrc, jpgSrcData);
|
||||
assert.equal(Session.cropImgWidth, 1);
|
||||
assert.equal(Session.cropImgHeight, 1);
|
||||
done();
|
||||
} catch (e) {
|
||||
return done(e);
|
||||
}
|
||||
});
|
||||
view.render()
|
||||
.then(function () {
|
||||
view.router.on('navigate', function () {
|
||||
try {
|
||||
assert.equal(routerMock.page, 'settings/avatar/crop');
|
||||
assert.include(Session.cropImgSrc, jpgSrcData);
|
||||
assert.equal(Session.cropImgWidth, 1);
|
||||
assert.equal(Session.cropImgHeight, 1);
|
||||
done();
|
||||
} catch (e) {
|
||||
return done(e);
|
||||
}
|
||||
});
|
||||
|
||||
view.$('.url').val('http://example.com/logo.jpg');
|
||||
view.submit();
|
||||
})
|
||||
.fail(done);
|
||||
view.$('.url').val('http://example.com/logo.jpg');
|
||||
view.submit();
|
||||
})
|
||||
.fail(done);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -27,34 +27,35 @@ module.exports = function (grunt) {
|
|||
grunt.task.renameTask('connect_fonts', 'do_connect_fonts');
|
||||
|
||||
grunt.task.registerTask('connect_fonts',
|
||||
'configure connect fonts based on the currently selected config', function () {
|
||||
// server config is not available on startup and is set in the
|
||||
// selectconfig task. configure_connect_fonts should be run after
|
||||
// selectconfig and before connect_fonts.
|
||||
var fontsDisabled = grunt.config.get('server.i18n.fonts.unsupportedLanguages');
|
||||
var supportedLanguages = grunt.config.get('server.i18n.supportedLanguages')
|
||||
.filter(function (lang) {
|
||||
return fontsDisabled.indexOf(lang) === -1;
|
||||
});
|
||||
'configure connect fonts based on the currently selected config',
|
||||
function () {
|
||||
// server config is not available on startup and is set in the
|
||||
// selectconfig task. configure_connect_fonts should be run after
|
||||
// selectconfig and before connect_fonts.
|
||||
var fontsDisabled = grunt.config.get('server.i18n.fonts.unsupportedLanguages');
|
||||
var supportedLanguages = grunt.config.get('server.i18n.supportedLanguages')
|
||||
.filter(function (lang) {
|
||||
return fontsDisabled.indexOf(lang) === -1;
|
||||
});
|
||||
|
||||
grunt.config('do_connect_fonts', {
|
||||
dist: {
|
||||
options: {
|
||||
fontPacks: fontPacks,
|
||||
fontNames: fontNamesNeeded,
|
||||
// languages will be configured in configure_connect_fonts
|
||||
languages: supportedLanguages,
|
||||
dest: '<%= yeoman.app %>/styles/fonts',
|
||||
destFileName: function (root, language) {
|
||||
// items on disk are stored by locale, not language.
|
||||
return path.join(root, i18n.localeFrom(language) + '.css');
|
||||
grunt.config('do_connect_fonts', {
|
||||
dist: {
|
||||
options: {
|
||||
fontPacks: fontPacks,
|
||||
fontNames: fontNamesNeeded,
|
||||
// languages will be configured in configure_connect_fonts
|
||||
languages: supportedLanguages,
|
||||
dest: '<%= yeoman.app %>/styles/fonts',
|
||||
destFileName: function (root, language) {
|
||||
// items on disk are stored by locale, not language.
|
||||
return path.join(root, i18n.localeFrom(language) + '.css');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
grunt.task.run(['do_connect_fonts']);
|
||||
});
|
||||
grunt.task.run(['do_connect_fonts']);
|
||||
});
|
||||
|
||||
grunt.config('connect_fonts_copy', {
|
||||
dist: {
|
||||
|
|
|
@ -12,7 +12,7 @@ module.exports = function (grunt) {
|
|||
'!<%= yeoman.app %>/scripts/vendor/**'
|
||||
],
|
||||
options: {
|
||||
config: '.jscs.json'
|
||||
config: '.jscsrc'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -45,26 +45,26 @@ module.exports = function (grunt) {
|
|||
|
||||
|
||||
grunt.registerTask('l10n-compile-templates',
|
||||
'Generate localized versions of the static pages', function () {
|
||||
'Generate localized versions of the static pages', function () {
|
||||
|
||||
var done = this.async();
|
||||
var done = this.async();
|
||||
|
||||
var i18n = require('../server/lib/i18n')(grunt.config.get('server.i18n'));
|
||||
var i18n = require('../server/lib/i18n')(grunt.config.get('server.i18n'));
|
||||
|
||||
// server config is set in the selectconfig task
|
||||
var supportedLanguages = grunt.config.get('server.i18n.supportedLanguages');
|
||||
defaultLang = grunt.config.get('server.i18n.defaultLang');
|
||||
// server config is set in the selectconfig task
|
||||
var supportedLanguages = grunt.config.get('server.i18n.supportedLanguages');
|
||||
defaultLang = grunt.config.get('server.i18n.defaultLang');
|
||||
|
||||
templateSrc = grunt.config.get('yeoman.page_template_src');
|
||||
templateDest = grunt.config.get('yeoman.page_template_dist');
|
||||
templateSrc = grunt.config.get('yeoman.page_template_src');
|
||||
templateDest = grunt.config.get('yeoman.page_template_dist');
|
||||
|
||||
// Legal templates have already been generated and placed in the template destination directory.
|
||||
var getTemplate = legalTemplates(i18n, templateDest);
|
||||
// Legal templates have already been generated and placed in the template destination directory.
|
||||
var getTemplate = legalTemplates(i18n, templateDest);
|
||||
|
||||
// Create a cache of the templates so we can reference them synchronously later
|
||||
Promise.settle(supportedLanguages.map(function (lang) {
|
||||
// Create a cache of the templates so we can reference them synchronously later
|
||||
Promise.settle(supportedLanguages.map(function (lang) {
|
||||
|
||||
return Promise.all([
|
||||
return Promise.all([
|
||||
getTemplate('terms', lang, defaultLang),
|
||||
getTemplate('privacy', lang, defaultLang)
|
||||
])
|
||||
|
@ -75,14 +75,14 @@ module.exports = function (grunt) {
|
|||
};
|
||||
});
|
||||
|
||||
})).then(function () {
|
||||
supportedLanguages.forEach(function (lang) {
|
||||
generatePagesForLanguage(i18n, lang);
|
||||
});
|
||||
done();
|
||||
}).then(null, done);
|
||||
})).then(function () {
|
||||
supportedLanguages.forEach(function (lang) {
|
||||
generatePagesForLanguage(i18n, lang);
|
||||
});
|
||||
done();
|
||||
}).then(null, done);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function generatePagesForLanguage(i18n, language) {
|
||||
|
@ -93,10 +93,9 @@ module.exports = function (grunt) {
|
|||
|
||||
grunt.file.recurse(templateSrc,
|
||||
function (srcPath, rootDir, subDir, fileName) {
|
||||
|
||||
var destPath = path.join(destRoot, (subDir || ''), fileName);
|
||||
generatePage(srcPath, destPath, context);
|
||||
});
|
||||
var destPath = path.join(destRoot, (subDir || ''), fileName);
|
||||
generatePage(srcPath, destPath, context);
|
||||
});
|
||||
}
|
||||
|
||||
function generatePage(srcPath, destPath, context) {
|
||||
|
|
|
@ -7,14 +7,14 @@ module.exports = function (grunt) {
|
|||
'use strict';
|
||||
|
||||
grunt.registerTask('l10n-generate-tos-pp',
|
||||
'Generate translated TOS/PP agreement partial templates',
|
||||
function () {
|
||||
'Generate translated TOS/PP agreement partial templates',
|
||||
function () {
|
||||
|
||||
grunt.task.run([
|
||||
'clean:tos_pp',
|
||||
'replace:tos_pp',
|
||||
'marked:tos_pp'
|
||||
]);
|
||||
});
|
||||
grunt.task.run([
|
||||
'clean:tos_pp',
|
||||
'replace:tos_pp',
|
||||
'marked:tos_pp'
|
||||
]);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ function makeApp() {
|
|||
// workaround for reserved word bug:
|
||||
// https://github.com/marijnh/acorn/issues/85
|
||||
app.use(express['static'](STATIC_DIRECTORY, {
|
||||
maxAge: config.get('static_max_age')
|
||||
maxAge: config.get('static_max_age')
|
||||
}));
|
||||
|
||||
// it's a four-oh-four not found.
|
||||
|
@ -116,8 +116,8 @@ function listen(theApp) {
|
|||
// Development only... Ops runs this behind nginx
|
||||
port = config.get('port');
|
||||
var tlsoptions = {
|
||||
key: fs.readFileSync(config.get('key_path')),
|
||||
cert: fs.readFileSync(config.get('cert_path'))
|
||||
key: fs.readFileSync(config.get('key_path')),
|
||||
cert: fs.readFileSync(config.get('cert_path'))
|
||||
};
|
||||
|
||||
https.createServer(tlsoptions, app).listen(port);
|
||||
|
|
|
@ -169,16 +169,18 @@ var conf = module.exports = convict({
|
|||
format: Array,
|
||||
// the big list of locales is specified so the production build script
|
||||
// can build all the locales before config/production.json is written.
|
||||
default: ['af', 'an', 'ar', 'as', 'ast', 'be', 'bg', 'bn-BD', 'bn-IN', 'br',
|
||||
'bs', 'ca', 'cs', 'cy', 'da', 'de', 'dsb', 'el', 'en-GB', 'en-US', 'en-ZA',
|
||||
'eo', 'es', 'es-AR', 'es-CL', 'es-MX', 'et', 'eu', 'fa', 'ff', 'fi',
|
||||
'fr', 'fy', 'fy-NL', 'ga', 'ga-IE', 'gd', 'gl', 'gu', 'gu-IN', 'he',
|
||||
'hi-IN', 'hr', 'hsb', 'ht', 'hu', 'hy-AM', 'id', 'is', 'it', 'it-CH', 'ja',
|
||||
'kk', 'km', 'kn', 'ko', 'ku', 'lij', 'lt', 'lv', 'mai', 'mk', 'ml',
|
||||
'mr', 'ms', 'nb-NO', 'ne-NP', 'nl', 'nn-NO', 'or', 'pa', 'pa-IN',
|
||||
'pl', 'pt', 'pt-BR', 'pt-PT', 'rm', 'ro', 'ru', 'si', 'sk', 'sl',
|
||||
'son', 'sq', 'sr', 'sr-LATN', 'sv', 'sv-SE', 'ta', 'te', 'th', 'tr',
|
||||
'uk', 'ur', 'vi', 'xh', 'zh-CN', 'zh-TW', 'zu'],
|
||||
default: [
|
||||
'af', 'an', 'ar', 'as', 'ast', 'be', 'bg', 'bn-BD', 'bn-IN', 'br',
|
||||
'bs', 'ca', 'cs', 'cy', 'da', 'de', 'dsb', 'el', 'en-GB', 'en-US', 'en-ZA',
|
||||
'eo', 'es', 'es-AR', 'es-CL', 'es-MX', 'et', 'eu', 'fa', 'ff', 'fi',
|
||||
'fr', 'fy', 'fy-NL', 'ga', 'ga-IE', 'gd', 'gl', 'gu', 'gu-IN', 'he',
|
||||
'hi-IN', 'hr', 'hsb', 'ht', 'hu', 'hy-AM', 'id', 'is', 'it', 'it-CH', 'ja',
|
||||
'kk', 'km', 'kn', 'ko', 'ku', 'lij', 'lt', 'lv', 'mai', 'mk', 'ml',
|
||||
'mr', 'ms', 'nb-NO', 'ne-NP', 'nl', 'nn-NO', 'or', 'pa', 'pa-IN',
|
||||
'pl', 'pt', 'pt-BR', 'pt-PT', 'rm', 'ro', 'ru', 'si', 'sk', 'sl',
|
||||
'son', 'sq', 'sr', 'sr-LATN', 'sv', 'sv-SE', 'ta', 'te', 'th', 'tr',
|
||||
'uk', 'ur', 'vi', 'xh', 'zh-CN', 'zh-TW', 'zu'
|
||||
],
|
||||
env: 'I18N_SUPPORTED_LANGUAGES'
|
||||
},
|
||||
translationDirectory: {
|
||||
|
@ -197,10 +199,12 @@ var conf = module.exports = convict({
|
|||
unsupportedLanguages: {
|
||||
doc: 'These languages should use system fonts instead of Fira Sans',
|
||||
format: Array,
|
||||
default: [ 'an', 'ar', 'as', 'ast', 'bn-DB', 'bn-IN', 'fa', 'ff', 'gd',
|
||||
'gu', 'gu-IN', 'he', 'hi-IN', 'ht', 'hy-AM', 'ja', 'km', 'kn', 'ko', 'lij',
|
||||
'mai', 'ml', 'mr', 'ne-NP', 'or', 'pa', 'pa-IN', 'si', 'son', 'ta', 'te',
|
||||
'th', 'ur', 'vi', 'zh-CN', 'zh-TW' ]
|
||||
default: [
|
||||
'an', 'ar', 'as', 'ast', 'bn-DB', 'bn-IN', 'fa', 'ff', 'gd',
|
||||
'gu', 'gu-IN', 'he', 'hi-IN', 'ht', 'hy-AM', 'ja', 'km', 'kn', 'ko', 'lij',
|
||||
'mai', 'ml', 'mr', 'ne-NP', 'or', 'pa', 'pa-IN', 'si', 'son', 'ta', 'te',
|
||||
'th', 'ur', 'vi', 'zh-CN', 'zh-TW'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -213,12 +217,12 @@ var conf = module.exports = convict({
|
|||
}
|
||||
},
|
||||
key_path: {
|
||||
doc: 'The location of the SSL key in pem format',
|
||||
default: path.resolve(__dirname, '..', '..', 'key.pem')
|
||||
doc: 'The location of the SSL key in pem format',
|
||||
default: path.resolve(__dirname, '..', '..', 'key.pem')
|
||||
},
|
||||
cert_path: {
|
||||
doc: 'The location of the SSL certificate in pem format',
|
||||
default: path.resolve(__dirname, '..', '..', 'cert.pem')
|
||||
doc: 'The location of the SSL certificate in pem format',
|
||||
default: path.resolve(__dirname, '..', '..', 'cert.pem')
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -11,19 +11,19 @@ var helmet = require('helmet');
|
|||
var config = require('./configuration');
|
||||
|
||||
var cspMiddleware = helmet.csp({
|
||||
'default-src': ['\'self\''],
|
||||
'connect-src': [
|
||||
'\'self\'',
|
||||
config.get('fxaccount_url'),
|
||||
config.get('oauth_url')
|
||||
],
|
||||
'img-src': [
|
||||
'\'self\'',
|
||||
'data:',
|
||||
'https://www.gravatar.com'
|
||||
],
|
||||
'report-uri': '/_/csp-violation'
|
||||
});
|
||||
'default-src': ['\'self\''],
|
||||
'connect-src': [
|
||||
'\'self\'',
|
||||
config.get('fxaccount_url'),
|
||||
config.get('oauth_url')
|
||||
],
|
||||
'img-src': [
|
||||
'\'self\'',
|
||||
'data:',
|
||||
'https://www.gravatar.com'
|
||||
],
|
||||
'report-uri': '/_/csp-violation'
|
||||
});
|
||||
|
||||
module.exports = function (req, res, next) {
|
||||
if (! requiresCsp(req)) {
|
||||
|
|
|
@ -29,11 +29,11 @@ module.exports = function () {
|
|||
return config.get('disable_route_logging')
|
||||
? disabled
|
||||
: expressLogger({
|
||||
format: formats[config.get('route_log_format')],
|
||||
stream: {
|
||||
write: function (x) {
|
||||
logger.info(typeof x === 'string' ? x.trim() : x);
|
||||
}
|
||||
format: formats[config.get('route_log_format')],
|
||||
stream: {
|
||||
write: function (x) {
|
||||
logger.info(typeof x === 'string' ? x.trim() : x);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -62,23 +62,23 @@ function getCommitHashFromGit() {
|
|||
|
||||
var l10nVersion = (function () {
|
||||
var version;
|
||||
try {
|
||||
try {
|
||||
var bowerPath = '../../../app/bower_components/fxa-content-server-l10n/.bower.json';
|
||||
var bowerInfo = require(bowerPath);
|
||||
version = bowerInfo && bowerInfo._release;
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
return version || 'unknown';
|
||||
})();
|
||||
|
||||
var tosPpVersion = (function () {
|
||||
var version;
|
||||
try {
|
||||
try {
|
||||
var bowerPath = '../../../app/bower_components/tos-pp/.bower.json';
|
||||
var bowerInfo = require(bowerPath);
|
||||
version = bowerInfo && bowerInfo._release;
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
return version || 'unknown';
|
||||
})();
|
||||
|
||||
|
@ -127,4 +127,3 @@ exports.process = function (req, res) {
|
|||
res.json(versionInfo);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ define([
|
|||
var self = this;
|
||||
return client.signUp(email, PASSWORD, { preVerified: true })
|
||||
.then(function () {
|
||||
return FunctionalHelpers.clearBrowserState(self);
|
||||
})
|
||||
return FunctionalHelpers.clearBrowserState(self);
|
||||
})
|
||||
.then(function () {
|
||||
return self.get('remote')
|
||||
.get(require.toUrl(SIGNIN_URL))
|
||||
|
|
|
@ -171,7 +171,7 @@ define([
|
|||
.end()
|
||||
|
||||
.then(FunctionalHelpers.visibleByQSA('.success'))
|
||||
|
||||
|
||||
.findByClassName('success').isDisplayed()
|
||||
.then(function (isDisplayed) {
|
||||
assert.equal(isDisplayed, true);
|
||||
|
|
|
@ -38,9 +38,9 @@ define([
|
|||
|
||||
var self = this;
|
||||
return client.signUp(email, FIRST_PASSWORD, { preVerified: true })
|
||||
.then(function () {
|
||||
return FunctionalHelpers.clearBrowserState(self);
|
||||
});
|
||||
.then(function () {
|
||||
return FunctionalHelpers.clearBrowserState(self);
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function () {
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
// These default settings work OK for most people. The options that *must* be changed below are the
|
||||
// packages, suites, excludeInstrumentation, and (if you want functional tests) functionalSuites.
|
||||
define([
|
||||
'intern/lib/args',
|
||||
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/topic',
|
||||
'./tools/firefox_profile'
|
||||
],
|
||||
function (args, topic, firefoxProfile) {
|
||||
'intern/lib/args',
|
||||
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/topic',
|
||||
'./tools/firefox_profile'
|
||||
],
|
||||
function (args, topic, firefoxProfile) {
|
||||
'use strict';
|
||||
|
||||
var fxaAuthRoot = args.fxaAuthRoot || 'http://127.0.0.1:9000/v1';
|
||||
|
|
|
@ -51,19 +51,19 @@ define([
|
|||
var dfd = this.async(1000);
|
||||
|
||||
request(serverUrl + '/template' + name, dfd.callback(function(err, res, body) {
|
||||
var json = JSON.parse(body);
|
||||
var json = JSON.parse(body);
|
||||
|
||||
assert.match(json.subject, matches.subject);
|
||||
assert.match(json.text, matches.text);
|
||||
assert.match(json.html, matches.html);
|
||||
assert.match(json.subject, matches.subject);
|
||||
assert.match(json.text, matches.text);
|
||||
assert.match(json.html, matches.html);
|
||||
|
||||
// make sure these variables are present and use {{
|
||||
assert.match(json.text, /{{{link}}}/);
|
||||
assert.match(json.html, /[^{]{{link}}/);
|
||||
assert.match(json.text, /{{{email}}}/);
|
||||
assert.match(json.html, /[^{]{{email}}/);
|
||||
// make sure these variables are present and use {{
|
||||
assert.match(json.text, /{{{link}}}/);
|
||||
assert.match(json.html, /[^{]{{link}}/);
|
||||
assert.match(json.text, /{{{email}}}/);
|
||||
assert.match(json.html, /[^{]{{email}}/);
|
||||
|
||||
}, dfd.reject.bind(dfd)));
|
||||
}, dfd.reject.bind(dfd)));
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -3,36 +3,35 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
define([
|
||||
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/node!path',
|
||||
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/node!execSync'
|
||||
],
|
||||
function (path, execSync) {
|
||||
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/node!path',
|
||||
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/node!execSync'
|
||||
],
|
||||
function (path, execSync) {
|
||||
'use strict';
|
||||
|
||||
'use strict';
|
||||
var createProfile = function(config) {
|
||||
var profileProcess = null;
|
||||
var encodedProfile = '';
|
||||
|
||||
var createProfile = function(config) {
|
||||
var profileProcess = null;
|
||||
var encodedProfile = '';
|
||||
|
||||
if (path) {
|
||||
console.log('Creating Firefox profile...');
|
||||
var profileArgs = JSON.stringify(JSON.stringify(config));
|
||||
var profileTool = path.join('tests', 'tools', 'firefox_profile_creator.js');
|
||||
try {
|
||||
profileProcess = execSync.exec(['node', profileTool, profileArgs].join(' '));
|
||||
} catch (e) {
|
||||
console.log('Note: execSync failed to run:', e);
|
||||
}
|
||||
|
||||
if (profileProcess && profileProcess.code === 0) {
|
||||
encodedProfile = profileProcess.stdout;
|
||||
} else {
|
||||
console.log('Note: Failed to generate a Firefox profile for this configuration.');
|
||||
}
|
||||
|
||||
return encodedProfile;
|
||||
if (path) {
|
||||
console.log('Creating Firefox profile...');
|
||||
var profileArgs = JSON.stringify(JSON.stringify(config));
|
||||
var profileTool = path.join('tests', 'tools', 'firefox_profile_creator.js');
|
||||
try {
|
||||
profileProcess = execSync.exec(['node', profileTool, profileArgs].join(' '));
|
||||
} catch (e) {
|
||||
console.log('Note: execSync failed to run:', e);
|
||||
}
|
||||
};
|
||||
|
||||
return createProfile;
|
||||
if (profileProcess && profileProcess.code === 0) {
|
||||
encodedProfile = profileProcess.stdout;
|
||||
} else {
|
||||
console.log('Note: Failed to generate a Firefox profile for this configuration.');
|
||||
}
|
||||
|
||||
return encodedProfile;
|
||||
}
|
||||
};
|
||||
|
||||
return createProfile;
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче