Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
460 lines
13 KiB
JavaScript
Executable file
460 lines
13 KiB
JavaScript
Executable file
'use strict';
|
|
|
|
/* global MocksHelper, InputLayouts, MockKeyboardManager,
|
|
MockKeyboardHelper, MockNavigatorMozSettings, MockNavigatorMozSettingsLock,
|
|
MockDOMRequest */
|
|
|
|
require('/test/unit/mock_keyboard_manager.js');
|
|
require('/test/unit/mock_custom_event.js');
|
|
require('/shared/test/unit/mocks/mock_keyboard_helper.js');
|
|
require('/shared/test/unit/mocks/mock_event_target.js');
|
|
require('/shared/test/unit/mocks/mock_dom_request.js');
|
|
require('/shared/js/input_mgmt/mock_navigator_mozsettings.js');
|
|
|
|
require('/js/input_layouts.js');
|
|
|
|
var mocksForInputLayouts = new MocksHelper([
|
|
'KeyboardHelper',
|
|
'KeyboardManager'
|
|
]).init();
|
|
|
|
suite('InputLayouts', function() {
|
|
var inputLayouts;
|
|
var realMozSettings;
|
|
var realMozInputMethod;
|
|
var setSupportsSwitchingTypesStub;
|
|
|
|
var appLayouts = [{
|
|
layoutId: 'en',
|
|
app: {
|
|
origin: 'app://k.gaiamobile.org',
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp'
|
|
},
|
|
inputManifest: {
|
|
launch_path: '/settings.html',
|
|
name: 'en',
|
|
types: ['text', 'number']
|
|
},
|
|
manifest: {
|
|
name: 'eng'
|
|
}
|
|
}];
|
|
|
|
mocksForInputLayouts.attachTestHelpers();
|
|
|
|
suiteSetup(function() {
|
|
realMozSettings = navigator.mozSettings;
|
|
});
|
|
|
|
suiteTeardown(function() {
|
|
navigator.mozSettings = realMozSettings;
|
|
});
|
|
|
|
setup(function() {
|
|
navigator.mozSettings = new MockNavigatorMozSettings();
|
|
|
|
inputLayouts = new InputLayouts(MockKeyboardManager, {
|
|
'text': 'textG',
|
|
'password': 'password',
|
|
'text2': 'textG'
|
|
});
|
|
|
|
realMozInputMethod = navigator.mozInputMethod;
|
|
setSupportsSwitchingTypesStub = this.sinon.stub();
|
|
navigator.mozInputMethod = {
|
|
mgmt: {
|
|
setSupportsSwitchingTypes: setSupportsSwitchingTypesStub
|
|
}
|
|
};
|
|
});
|
|
|
|
teardown(function() {
|
|
navigator.mozInputMethod = realMozInputMethod;
|
|
});
|
|
|
|
test('start() calls _getSettings', function() {
|
|
var stubGetSettings = this.sinon.stub(inputLayouts, '_getSettings');
|
|
inputLayouts.start();
|
|
assert.isTrue(stubGetSettings.called);
|
|
});
|
|
|
|
test('groupToTypeTable generation', function() {
|
|
assert.deepEqual(inputLayouts._groupToTypeTable, {
|
|
'textG': ['text', 'text2'],
|
|
'password': ['password']
|
|
});
|
|
});
|
|
|
|
test('transformLayout', function() {
|
|
var transformed = inputLayouts._transformLayout(appLayouts[0]);
|
|
// don't do deepEqual 'cause getters will not match
|
|
assert.equal(transformed.id, 'en');
|
|
assert.equal(transformed.origin, 'app://k.gaiamobile.org');
|
|
assert.equal(transformed.manifestURL,
|
|
'app://k.gaiamobile.org/manifest.webapp');
|
|
assert.equal(transformed.path, '/settings.html');
|
|
assert.equal(transformed.name, 'en');
|
|
assert.equal(transformed.appName, 'eng');
|
|
});
|
|
|
|
test('insertLayouts', function() {
|
|
this.sinon.stub(MockKeyboardHelper, 'isKeyboardType').returns(true);
|
|
var stubTransformLayout =
|
|
this.sinon.stub(inputLayouts, '_transformLayout').returns('LAYOUT');
|
|
|
|
inputLayouts._enabledApps = new Set();
|
|
|
|
inputLayouts._insertLayouts(appLayouts);
|
|
|
|
assert.isTrue(
|
|
inputLayouts._enabledApps.has('app://k.gaiamobile.org/manifest.webapp')
|
|
);
|
|
assert.isTrue('text' in inputLayouts.layouts);
|
|
assert.isTrue('number' in inputLayouts.layouts);
|
|
assert.isTrue(stubTransformLayout.calledWith(appLayouts[0]));
|
|
assert.deepEqual(inputLayouts.layouts.text, ['LAYOUT']);
|
|
assert.deepEqual(inputLayouts.layouts.number, ['LAYOUT']);
|
|
});
|
|
|
|
test('insertFallbackLayouts', function() {
|
|
var oldFallbackLayouts = MockKeyboardHelper.fallbackLayouts;
|
|
|
|
MockKeyboardHelper.fallbackLayouts = {
|
|
password: {
|
|
app: {
|
|
origin: 'app://keyboard.gaiamobile.org',
|
|
manifestURL: 'app://keyboard.gaiamobile.org/manifest.webapp'
|
|
},
|
|
layoutId: 'pwLayout',
|
|
inputManifest: {
|
|
launch_path: '/settings.html',
|
|
name: 'pwInput'
|
|
},
|
|
manifest: {
|
|
name: 'pwInput'
|
|
}
|
|
}
|
|
};
|
|
|
|
var stubTransformLayout =
|
|
this.sinon.stub(inputLayouts, '_transformLayout').returns('LAYOUT');
|
|
|
|
inputLayouts._enabledApps = new Set();
|
|
|
|
inputLayouts._insertFallbackLayouts();
|
|
|
|
assert.isTrue(
|
|
inputLayouts._enabledApps.has(
|
|
'app://keyboard.gaiamobile.org/manifest.webapp'
|
|
)
|
|
);
|
|
|
|
assert.isTrue(
|
|
stubTransformLayout.calledWith(
|
|
MockKeyboardHelper.fallbackLayouts.password
|
|
)
|
|
);
|
|
|
|
assert.deepEqual(inputLayouts.layouts.password, ['LAYOUT']);
|
|
|
|
MockKeyboardHelper.fallbackLayouts = oldFallbackLayouts;
|
|
});
|
|
|
|
test('setSupportsSwitchingTypes (w/ more than one layout enabled)',
|
|
function() {
|
|
inputLayouts.layouts = {
|
|
'text': ['en', 'fr', 'zh-hans'],
|
|
'password': ['en', 'fr'],
|
|
'number': []
|
|
};
|
|
|
|
var oldGroupToTypeTable = inputLayouts._groupToTypeTable;
|
|
inputLayouts._groupToTypeTable = {
|
|
'text': ['text', 'textarea'],
|
|
'password': ['password']
|
|
};
|
|
|
|
inputLayouts._setSupportsSwitchingTypes();
|
|
|
|
assert.isTrue(setSupportsSwitchingTypesStub
|
|
.calledWith(['text', 'textarea', 'password']));
|
|
|
|
inputLayouts._groupToTypeTable = oldGroupToTypeTable;
|
|
});
|
|
|
|
test('setSupportsSwitchingTypes (w/ only one layout enabled)', function() {
|
|
inputLayouts.layouts = {
|
|
'text': ['en'],
|
|
'password': ['en'],
|
|
'number': []
|
|
};
|
|
|
|
var oldGroupToTypeTable = inputLayouts._groupToTypeTable;
|
|
inputLayouts._groupToTypeTable = {
|
|
'text': ['text', 'textarea'],
|
|
'password': ['password']
|
|
};
|
|
|
|
inputLayouts._setSupportsSwitchingTypes();
|
|
|
|
assert.isTrue(setSupportsSwitchingTypesStub
|
|
.calledWith([]));
|
|
|
|
inputLayouts._groupToTypeTable = oldGroupToTypeTable;
|
|
});
|
|
|
|
|
|
test('generateToGroupMapping', function() {
|
|
inputLayouts.layouts = {
|
|
'text': [
|
|
{
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp',
|
|
id: 'en'
|
|
}, {
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp',
|
|
id: 'fr'
|
|
}, {
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp',
|
|
id: 'es'
|
|
}
|
|
],
|
|
'number': [
|
|
{
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp',
|
|
id: 'en'
|
|
}, {
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp',
|
|
id: 'es'
|
|
}, {
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp',
|
|
id: 'pt'
|
|
}, {
|
|
manifestURL: 'app://k2.gaiamobile.org/manifest.webapp',
|
|
id: 'romanNumerial'
|
|
}
|
|
]
|
|
};
|
|
inputLayouts._generateToGroupMapping();
|
|
|
|
assert.deepEqual(inputLayouts._layoutToGroupMapping, {
|
|
'app://k.gaiamobile.org/manifest.webapp/en':
|
|
[
|
|
{group: 'text', index: 0},
|
|
{group: 'number', index: 0}
|
|
],
|
|
'app://k.gaiamobile.org/manifest.webapp/fr':
|
|
[
|
|
{group: 'text', index: 1}
|
|
],
|
|
'app://k.gaiamobile.org/manifest.webapp/es':
|
|
[
|
|
{group: 'text', index: 2},
|
|
{group: 'number', index: 1}
|
|
],
|
|
'app://k.gaiamobile.org/manifest.webapp/pt':
|
|
[
|
|
{group: 'number', index: 2}
|
|
],
|
|
'app://k2.gaiamobile.org/manifest.webapp/romanNumerial':
|
|
[
|
|
{group: 'number', index: 3}
|
|
]
|
|
});
|
|
});
|
|
|
|
// we're not testing layouts[group]._activeLayoutIdx here as it's being tested
|
|
// (in an integrated sense) in KeyboardManager's "Try using the same layout
|
|
// when switching input types" test
|
|
test('saveGroupsCurrentActiveLayout', function() {
|
|
inputLayouts._layoutToGroupMapping = {
|
|
'app://k.gaiamobile.org/manifest.webapp/en': [
|
|
{group: 'text', index: 12},
|
|
{group: 'number', index: 34}
|
|
]
|
|
};
|
|
|
|
inputLayouts.layouts = {
|
|
'text': [],
|
|
'number': []
|
|
};
|
|
|
|
inputLayouts._currentActiveLayouts = {};
|
|
|
|
inputLayouts.layouts.text[12] = 'en';
|
|
inputLayouts.layouts.number[34] = 'en';
|
|
|
|
var stubMockNavigatorMozSettingsLock =
|
|
this.sinon.stub(MockNavigatorMozSettingsLock.prototype);
|
|
|
|
stubMockNavigatorMozSettingsLock.set.returns(new MockDOMRequest());
|
|
|
|
inputLayouts.saveGroupsCurrentActiveLayout({
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp',
|
|
id: 'en'
|
|
});
|
|
|
|
assert.equal(inputLayouts.layouts.text._activeLayoutIdx, 12,
|
|
'"text" activeLayout was not changed');
|
|
assert.equal(inputLayouts.layouts.number._activeLayoutIdx, 34,
|
|
'"number" activeLayout was not changed');
|
|
|
|
assert.isTrue(stubMockNavigatorMozSettingsLock.set.calledWith(
|
|
{
|
|
'keyboard.current-active-layouts': {
|
|
text: {
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp',
|
|
id: 'en'
|
|
},
|
|
number: {
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp',
|
|
id: 'en'
|
|
}
|
|
}
|
|
}
|
|
));
|
|
});
|
|
|
|
test('processLayouts', function() {
|
|
var stubInsertLayouts = this.sinon.stub(inputLayouts, '_insertLayouts',
|
|
function() {
|
|
inputLayouts.layouts = {
|
|
text: ['en'],
|
|
password: ['en']
|
|
};
|
|
|
|
inputLayouts._enabledApps.add('app://k.gaiamobile.org/manifest.webapp');
|
|
});
|
|
|
|
var stubInsertFallbacklayouts =
|
|
this.sinon.stub(inputLayouts, '_insertFallbackLayouts');
|
|
|
|
var emitLayoutsCountStub =
|
|
this.sinon.stub(inputLayouts, '_setSupportsSwitchingTypes');
|
|
|
|
var enabledApps = inputLayouts.processLayouts(appLayouts);
|
|
|
|
assert.isTrue(stubInsertLayouts.calledWith(appLayouts));
|
|
assert.isTrue(stubInsertFallbacklayouts.called);
|
|
|
|
assert.isTrue(
|
|
Object.keys(inputLayouts.layouts).every(
|
|
group => inputLayouts.layouts[group]._activeLayoutIdx === undefined
|
|
)
|
|
);
|
|
|
|
assert.isTrue(emitLayoutsCountStub.called);
|
|
|
|
assert.isTrue(enabledApps.has('app://k.gaiamobile.org/manifest.webapp'));
|
|
assert.equal(enabledApps.size, 1);
|
|
});
|
|
|
|
suite('getGroupCurrentActiveLayoutIndexAsync', function() {
|
|
test('success route null', function(done) {
|
|
// we test three things in this test:
|
|
// 1. when _promise = null, if everything is good;
|
|
// 2. when _promise already has something (subsequent to 1),
|
|
// 2a. and resolves to some known layout
|
|
// 2b. and resolves to some unknown layout
|
|
// 2a and 2b are what KeyboardManager test used to test.
|
|
inputLayouts.layouts = {
|
|
text: [
|
|
{
|
|
id: 'fr',
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp'
|
|
},
|
|
{
|
|
id: 'en',
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp'
|
|
}
|
|
]
|
|
};
|
|
|
|
var stubMockNavigatorMozSettingsLock =
|
|
this.sinon.stub(MockNavigatorMozSettingsLock.prototype);
|
|
|
|
var step1 = function(){
|
|
inputLayouts._promise = null;
|
|
|
|
var req = new MockDOMRequest();
|
|
|
|
stubMockNavigatorMozSettingsLock.get.returns(req);
|
|
|
|
var p = inputLayouts.getGroupCurrentActiveLayoutIndexAsync('text');
|
|
|
|
assert.equal(stubMockNavigatorMozSettingsLock.get.callCount, 1);
|
|
assert.isTrue(
|
|
stubMockNavigatorMozSettingsLock.get
|
|
.calledWith('keyboard.current-active-layouts')
|
|
);
|
|
|
|
req.fireSuccess({
|
|
'keyboard.current-active-layouts': {
|
|
text: {
|
|
id: 'en',
|
|
manifestURL: 'app://k.gaiamobile.org/manifest.webapp'
|
|
}
|
|
}
|
|
});
|
|
|
|
p.then(step2);
|
|
};
|
|
|
|
var step2 = function(){
|
|
assert.notStrictEqual(inputLayouts._promise, null);
|
|
|
|
var p = inputLayouts.getGroupCurrentActiveLayoutIndexAsync('text');
|
|
|
|
// get should not be called again
|
|
assert.equal(stubMockNavigatorMozSettingsLock.get.callCount, 1);
|
|
|
|
p.then(currentActiveLayoutsIdx => {
|
|
assert.equal(currentActiveLayoutsIdx, 1);
|
|
|
|
step3();
|
|
});
|
|
};
|
|
|
|
var step3 = function(){
|
|
assert.notStrictEqual(inputLayouts._promise, null);
|
|
|
|
var p = inputLayouts.getGroupCurrentActiveLayoutIndexAsync('number');
|
|
|
|
// get should not be called again
|
|
assert.equal(stubMockNavigatorMozSettingsLock.get.callCount, 1);
|
|
|
|
p.then(currentActiveLayoutsIdx => {
|
|
assert.strictEqual(currentActiveLayoutsIdx, undefined);
|
|
|
|
done();
|
|
});
|
|
};
|
|
|
|
step1();
|
|
});
|
|
|
|
test('_getSettings throws and resets _promise on error', function(done) {
|
|
var stubMockNavigatorMozSettingsLock =
|
|
this.sinon.stub(MockNavigatorMozSettingsLock.prototype);
|
|
|
|
inputLayouts._promise = null;
|
|
|
|
var req = new MockDOMRequest();
|
|
|
|
stubMockNavigatorMozSettingsLock.get.returns(req);
|
|
|
|
var p = inputLayouts.getGroupCurrentActiveLayoutIndexAsync('text');
|
|
|
|
assert.notStrictEqual(inputLayouts._promise, null);
|
|
|
|
// we want to catch that throw to not disrupt test flow
|
|
p.catch(e => {
|
|
assert.equal(e, 'error!');
|
|
assert.strictEqual(inputLayouts._promise, null);
|
|
|
|
done();
|
|
});
|
|
|
|
req.fireError('error!');
|
|
});
|
|
});
|
|
});
|