Skip to content

Instantly share code, notes, and snippets.

@crh0716
Created March 17, 2014 10:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crh0716/e3ec6f0881a5f878d964 to your computer and use it in GitHub Desktop.
Save crh0716/e3ec6f0881a5f878d964 to your computer and use it in GitHub Desktop.
'use strict';
requireApp('system/test/unit/mock_apps_mgmt.js');
requireApp('system/test/unit/mock_app.js');
mocha.globals(['FxAccountsIACHelper']);
// XXX consider moving this to a separate file if it gets much more complex
var port = {
postMessage: function(message) {
var msg = {
data: {
data: {},
methodName: message.name
}
};
setTimeout(function() {
port._onmessage(msg);
});
},
_onmessage: null,
set onmessage(cb) {
port._onmessage = cb;
}
};
suite('FirefoxOS Accounts IAC Client Suite', function() {
var realMozApps;
var postMessageStub;
suiteSetup(function() {
realMozApps = navigator.mozApps;
navigator.mozApps = MockAppsMgmt;
});
suiteTeardown(function() {
navigator.mozApps = realMozApps;
});
setup(function(done) {
// For each test, setup the 'self' app, able to
// do IAC
var app = new MockApp({
'connect': function(keyword) {
var future = {
'then': function(cb) {}
};
var connectStub = sinon.stub(future, 'then', function(cb) {
cb([port]);
});
return future;
}
});
navigator.mozApps.setSelf(app);
// XXX we have to require() the system under test *after* we define the
// MockApp, because the code calls app.connect() as soon as it is loaded
require('/shared/js/fxa_iac_client.js', done);
});
teardown(function() {
if (postMessageStub && postMessageStub.restore) {
postMessageStub.restore();
}
});
test('Library integrity', function() {
assert.isNotNull(FxAccountsIACHelper);
assert.equal(Object.keys(FxAccountsIACHelper).length, 8);
});
['getAccounts', 'openFlow', 'logout'].forEach(function(method) {
suite(method + ' suite', function() {
setup(function() {
postMessageStub = sinon.spy(port, 'postMessage');
});
test('Check that we send the ' + method + ' message', function(done) {
this.timeout(20000);
FxAccountsIACHelper[method](
function() {
assert.ok(postMessageStub.called);
var arg = postMessageStub.args[0][0];
// We do have an id for this message
assert.isNotNull(arg.id);
assert.isNotNull(arg);
// Remove the id, as it's automatically generated
delete arg.id;
assert.deepEqual(arg, {
'name': method
});
done();
},
function() {
// Break if we are called.
assert.ok(false);
done();
}
);
});
teardown(function() {
postMessageStub.restore();
});
});
});
suite('refreshAuthentication suite', function() {
setup(function() {
postMessageStub = sinon.spy(port, 'postMessage');
});
test('Check that we send the refreshAuth message', function(done) {
this.timeout(20000);
FxAccountsIACHelper.refreshAuthentication('dummy@domain.org',
function() {
assert.ok(postMessageStub.called);
var arg = postMessageStub.args[0][0];
// We do have an id for this message
assert.isNotNull(arg.id);
assert.isNotNull(arg);
// Remove the id, as it's automatically generated
delete arg.id;
assert.deepEqual(arg, {
'name': 'refreshAuthentication',
'accountId': 'dummy@domain.org'
});
done();
},
function() {
// Break if we are called.
assert.ok(false);
done();
}
);
});
teardown(function() {
postMessageStub.restore();
});
});
suite('addEventListener tests', function() {
var callbackCalled = false;
var otherCallbackCalled = false;
var listener = function() {
callbackCalled = true;
};
var otherListener = function() {
otherCallbackCalled = true;
};
setup(function() {
FxAccountsIACHelper.addEventListener('myEvent', listener);
FxAccountsIACHelper.addEventListener('myOtherEvent', otherListener);
port._onmessage({
data: {
data: {},
eventName: 'myEvent'
}
});
});
test('Check that we trigger the appropriate callback', function() {
assert.ok(callbackCalled);
assert.ok(!otherCallbackCalled);
});
teardown(function() {
FxAccountsIACHelper.removeEventListener('myEvent', listener);
FxAccountsIACHelper.removeEventListener('myOtherEvent', otherListener);
});
});
suite('removeEventListener tests', function() {
var callbackCalled = false;
var otherCallbackCalled = false;
var listener = function() {
callbackCalled = true;
};
var otherListener = function() {
otherCallbackCalled = true;
};
setup(function() {
FxAccountsIACHelper.addEventListener('myEvent', listener);
FxAccountsIACHelper.addEventListener('myOtherEvent', otherListener);
FxAccountsIACHelper.removeEventListener('myEvent', listener);
port._onmessage({
data: {
data: {},
eventName: 'myEvent'
}
});
port._onmessage({
data: {
data: {},
eventName: 'myOtherEvent'
}
});
});
test('Check that we trigger the appropriate callback', function() {
assert.ok(!callbackCalled);
assert.ok(otherCallbackCalled);
});
});
suite('Startup race condition tests - bug 974108', function() {
var callbackCalled, otherCallbackCalled;
var listener = function() {
callbackCalled = true;
};
var otherListener = function() {
otherCallbackCalled = true;
};
setup(function() {
this.clock = sinon.useFakeTimers();
var callbackCalled = false;
var otherCallbackCalled = false;
// we are testing that postmessage requests are queued, not overwritten,
// during the period between starting the Helper and the port being open.
// we need to clear out the port, add 2 new subscribers, then check both
// are called.
var app = new MockApp({
'connect': function(keyword) {
var future = {
'then': function(cb) {}
};
var connectStub = sinon.stub(future, 'then', function(cb) {
// wait a turn so that we can queue up multiple requests
setTimeout(function() {
cb([port]);
}, 0);
});
return future;
}
});
navigator.mozApps.setSelf(app);
FxAccountsIACHelper.reset();
});
teardown(function() {
this.clock.restore();
});
test('Should queue multiple requests until port is opened', function() {
callbackCalled = false;
otherCallbackCalled = false;
// reset() will destroy the existing port, forcing message requests
// to be queued up.
FxAccountsIACHelper.reset();
// two requests -- one to be sent as soon as the connection's ready,
// the other after that.
FxAccountsIACHelper.logout(otherListener);
FxAccountsIACHelper.getAccounts(listener);
this.clock.tick(1000);
assert.isTrue(callbackCalled);
assert.isTrue(otherCallbackCalled);
});
test('Should queue multiple callbacks for one request', function() {
callbackCalled = false;
otherCallbackCalled = false;
FxAccountsIACHelper.reset();
FxAccountsIACHelper.getAccounts(listener);
FxAccountsIACHelper.getAccounts(otherListener);
this.clock.tick(1000);
assert.isTrue(callbackCalled);
assert.isTrue(otherCallbackCalled);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment