VulpesOS/gaia/apps/system/test/unit/nfc_manager_test.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

1093 lines
36 KiB
JavaScript
Executable file

'use strict';
/* globals MockPromise, MockNfc, MockBluetooth, MocksHelper, NDEF,
MockService, NfcUtils, MozActivity, NfcHandoverManager,
MockNfcHandoverManager, BaseModule, MockLazyLoader */
require('/shared/test/unit/mocks/mock_lazy_loader.js');
require('/shared/test/unit/mocks/mock_settings_listener.js');
require('/shared/js/nfc_utils.js');
require('/shared/test/unit/mocks/mock_event_target.js');
require('/shared/test/unit/mocks/mock_promise.js');
requireApp('system/test/unit/mock_app_window.js');
requireApp('system/test/unit/mock_activity.js');
requireApp('system/test/unit/mock_nfc.js');
requireApp('system/test/unit/mock_nfc_handover_manager.js');
requireApp('system/test/unit/mock_bluetooth.js');
require('/shared/test/unit/mocks/mock_service.js');
requireApp('system/js/base_module.js');
requireApp('system/js/base_ui.js');
requireApp('system/js/base_icon.js');
requireApp('system/js/nfc_icon.js');
requireApp('system/js/nfc_manager.js');
var mocksForNfcManager = new MocksHelper([
'AppWindow',
'MozActivity',
'SettingsListener',
'NfcHandoverManager',
'Service',
'LazyLoader'
]).init();
var MockMessageHandlers = {};
function MockMozSetMessageHandler(event, handler) {
MockMessageHandlers[event] = handler;
}
suite('Nfc Manager Functions', function() {
var fakeApp;
var realMozSetMessageHandler;
var realMozBluetooth;
var realMozNfc;
var nfcUtils;
var nfcManager;
mocksForNfcManager.attachTestHelpers();
var fakeAppConfig = {
url: 'app://www.fake/index.html',
manifest: {},
manifestURL: 'app://wwww.fake/ManifestURL',
origin: 'app://www.fake',
instanceID: 'instanceID'
};
var fakePrivateLandingPage = {
url: 'app://search.gaiamobile.org/',
manifest: {},
origin: 'http://www.private',
isPrivate: true
};
var fakeBrowserForFullscreen = {
url: 'app://browser.gaiamobile.org/',
manifest: {},
origin: 'http://somevideo',
isBrowser: function() { return true; }
};
setup(function() {
window.NfcHandoverManager = MockNfcHandoverManager;
MockLazyLoader.mLaodRightAway = true;
this.sinon.spy(MockLazyLoader, 'load');
fakeApp = new window.AppWindow(fakeAppConfig);
realMozSetMessageHandler = window.navigator.mozSetMessageHandler;
window.navigator.mozSetMessageHandler = MockMozSetMessageHandler;
realMozBluetooth = window.navigator.mozBluetooth;
Object.defineProperty(navigator, 'mozBluetooth', {
configurable: true,
get: function() {
return MockBluetooth;
}
});
realMozNfc = window.navigator.mozNfc;
window.navigator.mozNfc = MockNfc;
nfcUtils = new NfcUtils();
MockService.mockQueryWith('getTopMostWindow', fakeApp);
nfcManager = BaseModule.instantiate('NfcManager');
nfcManager.service = MockService;
nfcManager.start();
});
teardown(function() {
nfcManager.stop();
window.navigator.mozSetMessageHandler = realMozSetMessageHandler;
Object.defineProperty(navigator, 'mozBluetooth', {
configurable: true,
get: function() {
return realMozBluetooth;
}
});
window.navigator.mozNfc = realMozNfc;
});
suite('_start', function() {
test('Should lazy load icon', function() {
assert.isTrue(MockLazyLoader.load.calledWith(['js/nfc_icon.js']));
});
test('Message handleres for nfc-manager-tech-xxx set', function() {
var stubHandleTechnologyDiscovered =
this.sinon.stub(nfcManager, '_handleTechDiscovered');
var stubHandleTechLost = this.sinon.stub(nfcManager, '_handleTechLost');
MockMessageHandlers['nfc-manager-tech-discovered']();
assert.isTrue(stubHandleTechnologyDiscovered.calledOnce);
MockMessageHandlers['nfc-manager-tech-lost']();
assert.isTrue(stubHandleTechLost.calledOnce);
});
test('nfcManager listens on screenchange, and the locking events',
function() {
var stubScreenchange = this.sinon.stub(nfcManager,
'_handle_screenchange');
var stubLockscreenOn = this.sinon.stub(nfcManager,
'_handle_lockscreen-appopened');
var stubLockscreenOff = this.sinon.stub(nfcManager,
'_handle_lockscreen-appclosed');
window.dispatchEvent(new CustomEvent('lockscreen-appopened'));
assert.isTrue(stubLockscreenOn.calledOnce);
window.dispatchEvent(new CustomEvent('lockscreen-appclosed'));
assert.isTrue(stubLockscreenOff.calledOnce);
window.dispatchEvent(new CustomEvent('screenchange'));
assert.isTrue(stubScreenchange.calledOnce);
});
test('SettingsListner callback nfc.enabled fired', function() {
var enabled = 'test';
var stubNfcSettingObserver = this.sinon.stub(nfcManager,
'_observe_nfc.enabled');
nfcManager['_observe_nfc.enabled'](enabled);
assert.isTrue(stubNfcSettingObserver.calledWith(enabled));
});
test('Sets nfc.status setting to disabled', function() {
var stubWriteSetting = this.sinon.stub(nfcManager, 'writeSetting');
nfcManager._start();
assert.isTrue(stubWriteSetting.calledOnce);
assert.deepEqual(stubWriteSetting.firstCall.args[0],
{ 'nfc.status': 'disabled' });
});
});
suite('_stop', function() {
test('removes message handlers', function() {
var setHandlerStub = this.sinon.stub(window.navigator,
'mozSetMessageHandler');
nfcManager._stop();
assert.isTrue(setHandlerStub.withArgs('nfc-manager-tech-discovered', null)
.calledOnce);
assert.isTrue(setHandlerStub.withArgs('nfc-manager-tech-lost', null)
.calledOnce);
});
});
suite('isActive', function() {
test('returns false if hardware state is OFF', function() {
nfcManager._hwState = 'disabled';
assert.isFalse(nfcManager.isActive());
});
test('returns false if hardware state is a transition state', function() {
nfcManager._hwState = 'enabling';
assert.isFalse(nfcManager.isActive());
nfcManager._hwState = 'disabling';
assert.isFalse(nfcManager.isActive());
});
test('returns true if hardware state is ON', function() {
nfcManager._hwState = 'enabled';
assert.isTrue(nfcManager.isActive());
});
test('returns true if hardware state is ENABLE_DISCOVERY', function() {
nfcManager._hwState = 'polling-on';
assert.isTrue(nfcManager.isActive());
});
test('returns true if hardware state is DISABLE_DISCOVERY', function() {
nfcManager._hwState = 'polling-off';
assert.isTrue(nfcManager.isActive());
});
});
suite('_handle_<event_name>', function() {
var stubDoTransition;
setup(function() {
stubDoTransition = this.sinon.stub(nfcManager, '_doNfcStateTransition');
});
teardown(function() {
stubDoTransition.restore();
});
test('lockscreen-appopened -> disable-polling', function() {
window.dispatchEvent(new CustomEvent('lockscreen-appopened'));
assert.isTrue(stubDoTransition.withArgs('disable-polling').calledOnce);
});
test('lockscreen-appclosed -> enable-polling', function() {
window.dispatchEvent(new CustomEvent('lockscreen-appclosed'));
assert.isTrue(stubDoTransition.withArgs('enable-polling').calledOnce);
});
test('screenchange -> enable-polling/disable-polling', function() {
MockService.mockQueryWith('screenEnabled', false);
window.dispatchEvent(new CustomEvent('screenchange'));
assert.isTrue(stubDoTransition.withArgs('disable-polling').calledOnce);
MockService.mockQueryWith('screenEnabled', true);
MockService.mockQueryWith('locked', true);
window.dispatchEvent(new CustomEvent('screenchange'));
assert.isTrue(stubDoTransition.withArgs('disable-polling').calledTwice);
MockService.mockQueryWith('locked', false);
window.dispatchEvent(new CustomEvent('screenchange'));
assert.isTrue(stubDoTransition.withArgs('enable-polling').calledOnce);
});
});
suite('_handleTechDiscovered', function() {
var sampleMsg;
var sampleURIRecord;
var sampleMimeRecord;
setup(function() {
sampleMsg = {
type: 'techDiscovered',
records: [],
peer: MockNfc.MockNFCPeer
};
// NDEF TNF well know uri unabbreviated
sampleURIRecord = {
tnf: NDEF.TNF_WELL_KNOWN,
type: NDEF.RTD_URI,
id: new Uint8Array([1]),
payload: nfcUtils.fromUTF8('\u0000http://mozilla.org')
};
sampleMimeRecord = {
tnf: NDEF.TNF_MIME_MEDIA,
type: nfcUtils.fromUTF8('text/vcard'),
id: new Uint8Array([2]),
payload: nfcUtils.fromUTF8('BEGIN:VCARD\nVERSION:2.1\nN:J;\nEND:VCARD')
};
nfcManager.nfcHandoverManager = MockNfcHandoverManager;
});
// Helper methods, can be called multiple times in testcase, stubs and spies
// need to be restored here.
// invalid message test helper
var execInvalidMessageTest = function(msg) {
var stubVibrate = this.sinon.stub(window.navigator, 'vibrate');
var stubDispatchEvent = this.sinon.stub(window, 'dispatchEvent');
var stubTryHandover = this.sinon.stub(NfcHandoverManager, 'tryHandover');
var stubFireNDEF = this.sinon.stub(nfcManager, '_fireNDEFDiscovered');
var stubCheckP2P = this.sinon.stub(nfcManager, '_checkP2PRegistration');
nfcManager._handleTechDiscovered(msg);
assert.isTrue(stubVibrate.withArgs([25, 50, 125]).calledOnce,
'wrong vibrate, when msg: ' + msg);
assert.isTrue(stubDispatchEvent.calledOnce,
'dispatchEvent not called once, when msg: ' + msg);
assert.equal(stubDispatchEvent.getCall(0).args[0].type,
'nfc-tech-discovered',
'when msg ' + msg);
assert.isTrue(stubTryHandover.withArgs([], undefined)
.calledOnce, 'handover, when msg: ' + msg);
assert.isFalse(stubFireNDEF.called,
'_fireNDEFDiscovered should not be called');
assert.isFalse(stubCheckP2P.called,
'checkP2PRegistration should not be called');
stubVibrate.restore();
stubDispatchEvent.restore();
stubTryHandover.restore();
stubFireNDEF.restore();
stubCheckP2P.restore();
};
// _fireNDEFDiscovered test helper
var execNDEFMessageTest = function(msg) {
var stub = this.sinon.stub(nfcManager, '_fireNDEFDiscovered');
nfcManager._handleTechDiscovered(msg);
assert.isTrue(stub.withArgs(msg.records).calledOnce);
stub.restore();
};
// checkP2PRegistration helper.
var execCheckP2PRegistrationTest = function(msg) {
var stub = this.sinon.stub(nfcManager, '_checkP2PRegistration');
nfcManager._handleTechDiscovered(msg);
assert.isTrue(stub.calledOnce);
stub.restore();
};
test('valid message, proper methods called', function() {
sampleMsg.records.push(sampleURIRecord);
var stubVibrate = this.sinon.stub(window.navigator, 'vibrate');
var stubDispatchEvent = this.sinon.stub(window, 'dispatchEvent');
var stubTryHandover = this.sinon.stub(nfcManager.nfcHandoverManager,
'tryHandover');
nfcManager._handleTechDiscovered(sampleMsg);
assert.isTrue(stubVibrate.withArgs([25, 50, 125]).calledOnce, 'vibrate');
assert.equal(stubDispatchEvent.firstCall.args[0].type,
'nfc-tech-discovered');
assert.isTrue(stubTryHandover
.withArgs(sampleMsg.records, sampleMsg.peer)
.calledOnce, 'tryHandover');
});
test('invalid message handling', function() {
execInvalidMessageTest.call(this, null);
execInvalidMessageTest.call(this, {});
});
test('message with one NDEF URI record', function() {
sampleMsg.records.push(sampleURIRecord);
execNDEFMessageTest.call(this, sampleMsg);
});
test('message with NfcPeer, but no NDEF records', function() {
execCheckP2PRegistrationTest.call(this, sampleMsg);
});
test('massage with no NDEF records, no action', function() {
delete sampleMsg.peer;
execInvalidMessageTest.call(this, sampleMsg);
});
test('activities triggering end 2 end', function() {
// empty record
var empty = { tnf: NDEF.TNF_EMPTY };
sampleMsg.records.push(sampleURIRecord);
sampleMsg.records.push(empty);
sampleMsg.records.push(sampleMimeRecord);
this.sinon.stub(window, 'MozActivity');
nfcManager._handleTechDiscovered(sampleMsg);
assert.deepEqual(MozActivity.firstCall.args[0], {
name: 'view',
data: {
type: 'url',
url: 'http://mozilla.org',
src: 'nfc',
records: sampleMsg.records
}
}, 'Uri record');
sampleMsg.records.shift();
nfcManager._handleTechDiscovered(sampleMsg);
assert.deepEqual(MozActivity.secondCall.args[0], {
name: 'nfc-ndef-discovered',
data: {
type: 'empty',
records: sampleMsg.records
}
},'TNF empty');
sampleMsg.records.shift();
nfcManager._handleTechDiscovered(sampleMsg);
assert.deepEqual(MozActivity.thirdCall.args[0], {
name: 'import',
data: {
type: 'text/vcard',
blob: new Blob([nfcUtils.toUTF8(sampleMimeRecord.payload)],
{'type': 'text/vcard'}),
src: 'nfc',
records: sampleMsg.records
}
},'mime record');
});
});
suite('_handleTechLost', function() {
test('vibrates and dispatches nfc-tech-lost event', function() {
var stubVibrate = this.sinon.stub(window.navigator, 'vibrate');
var stubDispatchEvent = this.sinon.stub(window, 'dispatchEvent');
nfcManager._handleTechLost();
assert.isTrue(stubVibrate.withArgs([125, 50, 25]).calledOnce, 'vibrate');
assert.equal(stubDispatchEvent.firstCall.args[0].type, 'nfc-tech-lost');
});
test('P2P clean up', function() {
var stubCleanP2PUI = this.sinon.stub(nfcManager, '_cleanP2PUI');
nfcManager._handleTechLost();
assert.isTrue(stubCleanP2PUI.calledOnce);
});
});
suite('_doNfcStateTransition', function() {
var events = ['enable', 'disable', 'enable-polling', 'disable-polling',
'hw-change-success', 'hw-change-failure', 'unknown-event'];
// { state: { event: new_state }}
var stateTransitions = {
'disabling': {
'hw-change-success': 'disabled',
'hw-change-failure': 'enabled'
},
'disabled': { 'enable': 'enabling' },
'enabling': {
'hw-change-success': 'enabled',
'hw-change-failure': 'disabled'
},
'enabled': {
'disable': 'disabling',
'enable-polling': 'polling-on',
'disable-polling': 'polling-off'
},
'polling-on': {
'disable': 'disabling',
'disable-polling': 'polling-off'
},
'polling-off': {
'disable': 'disabling',
'enable-polling': 'polling-on'
}
};
Object.keys(stateTransitions).forEach(function(state) {
test('"' + state + '" state transitions', function() {
var stubProccessStateChange = this.sinon.stub(nfcManager,
'_processNfcStateChange');
events.forEach(function(evt, idx) {
nfcManager._hwState = state;
nfcManager._doNfcStateTransition(evt);
var expectedState = stateTransitions[state][evt] || state;
assert.equal(nfcManager._hwState, expectedState,
state + '[' + evt + '] should be ' + expectedState);
});
assert.equal(stubProccessStateChange.callCount,
Object.keys(stateTransitions[state]).length,
'_processNfcStateChange should be called on transition');
});
});
});
suite('_processNfcStateChange', function() {
var states = ['disabling', 'disabled', 'enabling', 'enabled',
'polling-off', 'polling-on'];
var fakePromise;
var stubPowerOff, stubStartPoll, stubStopPoll;
var stubIconUpdate, stubWriteSetting, stubNfcTransition;
setup(function() {
fakePromise = new MockPromise();
var handler = () => fakePromise;
stubPowerOff = this.sinon.stub(MockNfc, 'powerOff', handler);
stubStartPoll = this.sinon.stub(MockNfc, 'startPoll', handler);
stubStopPoll = this.sinon.stub(MockNfc, 'stopPoll', handler);
stubIconUpdate = this.sinon.stub(nfcManager.icon, 'update');
stubWriteSetting = this.sinon.stub(nfcManager, 'writeSetting');
stubNfcTransition = this.sinon.stub(nfcManager, '_doNfcStateTransition');
});
teardown(function() {
stubPowerOff.restore();
stubStartPoll.restore();
stubStopPoll.restore();
stubIconUpdate.restore();
stubWriteSetting.restore();
stubNfcTransition.restore();
});
states.forEach(function(state) {
test('"' + state + '" state handlind', function() {
nfcManager._hwState = state;
nfcManager._processNfcStateChange();
// icon updated in proper states
if (state === 'enabled' || state === 'disabled') {
assert.isTrue(stubIconUpdate.calledOnce,
'icon should be updated');
} else {
assert.isTrue(stubIconUpdate.notCalled,
'icon should not be update');
}
// write setting in proper states
if (state === 'polling-on' || state === 'polling-off') {
assert.isTrue(stubWriteSetting.notCalled,
'should not call writeSetting');
} else {
assert.isTrue(stubWriteSetting.calledOnce,
'should call writeSetting');
assert.deepEqual(stubWriteSetting.firstCall.args[0],
{ 'nfc.status': state });
}
// proper hw changes
if (state === 'disabling') {
assert.isTrue(stubPowerOff.calledOnce,
'mozNfc.powerOff should be called');
} else {
assert.isTrue(stubPowerOff.notCalled,
'mozNfc.powerOff should not be called');
}
if (state === 'enabling' || state === 'polling-on') {
assert.isTrue(stubStartPoll.calledOnce,
'mozNfc.startPoll should be called');
} else {
assert.isTrue(stubStartPoll.notCalled,
'mozNfc.stopPoll should not be called');
}
if (state === 'polling-off') {
assert.isTrue(stubStopPoll.calledOnce,
'mozNfc.stopPoll should be called');
} else {
assert.isTrue(stubStopPoll.notCalled,
'mozNfc.stopPoll should not be called');
}
// proper promise handling
if (state === 'enabled' || state === 'disabled') {
assert.isTrue(fakePromise.then.notCalled,
'then should not be called on promise');
} else {
fakePromise.mFulfillToValue();
assert.isTrue(stubNfcTransition.withArgs('hw-change-success').called,
'_doNfcStateTransition(hw-change-success) not called');
fakePromise.mRejectToError();
assert.isTrue(stubNfcTransition.withArgs('hw-change-failure').called,
'_doNfcStateTransition(hw-change-failure) not called');
}
});
});
});
suite('_fireNDEFDiscovered', function() {
var records;
var uriRecord;
setup(function() {
records = [];
uriRecord = {
tnf: NDEF.TNF_WELL_KNOWN,
type: NDEF.RTD_URI,
id: new Uint8Array([1]),
payload: nfcUtils.fromUTF8('\u0000http://mozilla.org')
};
this.sinon.stub(window, 'MozActivity');
}),
teardown(function() {
window.MozActivity.restore();
}),
suite('NDEF.payload.decode called with proper args', function() {
var stubDecodePayload;
var smartPoster;
setup(function() {
smartPoster = {
tnf: NDEF.TNF_WELL_KNOWN,
type: NDEF.RTD_SMART_POSTER,
id: new Uint8Array([2]),
payload: 'fake payload'
};
stubDecodePayload = this.sinon.stub(NDEF.payload, 'decode',
() => null);
});
teardown(function() {
stubDecodePayload.restore();
});
test('Multiple records, first record decoded', function() {
records.push(uriRecord);
records.push({tnf: NDEF.TNF_EMPTY});
nfcManager._fireNDEFDiscovered(records);
assert.isTrue(stubDecodePayload.withArgs(uriRecord.tnf,
uriRecord.type,
uriRecord.payload)
.calledOnce);
});
test('SP (Smart Poster) takes precedence over URI record', function() {
records.push(uriRecord);
records.push(smartPoster);
nfcManager._fireNDEFDiscovered(records);
assert.isTrue(stubDecodePayload.withArgs(smartPoster.tnf,
smartPoster.type,
smartPoster.payload)
.calledOnce);
});
test('SP doesnt take precedence over other records', function() {
records.push({tnf: NDEF.TNF_EMPTY});
records.push(smartPoster);
nfcManager._fireNDEFDiscovered(records);
assert.isTrue(stubDecodePayload.withArgs(NDEF.TNF_EMPTY,
undefined,
undefined)
.calledOnce);
});
test('Empty NDEF message', function() {
nfcManager._fireNDEFDiscovered(records);
assert.isTrue(stubDecodePayload.withArgs(NDEF.TNF_EMPTY,
undefined,
undefined)
.calledOnce);
});
}),
test('_getSmartPoster called with proper arg', function() {
records.push(uriRecord);
var spyGetSmartPoster = this.sinon.spy(nfcManager, '_getSmartPoster');
nfcManager._fireNDEFDiscovered(records);
assert.isTrue(spyGetSmartPoster.withArgs(records).calledOnce);
}),
test('_createNDEFActivityOptions called with proper args', function() {
records.push(uriRecord);
var decoded = {};
this.sinon.stub(NDEF.payload, 'decode', () => decoded);
var spyCreateOptions = this.sinon.spy(nfcManager,
'_createNDEFActivityOptions');
nfcManager._fireNDEFDiscovered(records);
assert.isTrue(spyCreateOptions.withArgs(decoded).calledOnce);
}),
test('MozActivity called with proper args, valid NDEF', function() {
records.push(uriRecord);
nfcManager._fireNDEFDiscovered(records);
assert.deepEqual(MozActivity.firstCall.args[0], {
name: 'view',
data: {
type: 'url',
url: 'http://mozilla.org',
src: 'nfc',
records: records
}
});
});
test('MozActivity called with proper args, invalid NDEF', function() {
this.sinon.stub(NDEF.payload, 'decode', () => null);
nfcManager._fireNDEFDiscovered(records);
assert.deepEqual(MozActivity.firstCall.args[0],
{ name: 'nfc-ndef-discovered', data: {} });
});
}),
suite('_getSmartPoster', function() {
var smartPosterRecord;
var uriRecord;
var mimeRecord;
setup(function() {
smartPosterRecord = {
tnf: NDEF.TNF_WELL_KNOWN,
type: NDEF.RTD_SMART_POSTER,
id: new Uint8Array([1]),
paylod: nfcUtils.fromUTF8('dummy payload')
};
uriRecord = {
tnf: NDEF.TNF_WELL_KNOWN,
type: NDEF.RTD_URI,
id: new Uint8Array([2]),
payload: nfcUtils.fromUTF8('dummy uri')
};
mimeRecord = {
tnf: NDEF.TNF_MIME_MEDIA,
type: nfcUtils.fromUTF8('text/plain'),
id: new Uint8Array([3]),
payload: nfcUtils.fromUTF8('dummy text')
};
});
test('no Smart Poster (SP) - null returned', function() {
var result = nfcManager._getSmartPoster([uriRecord, mimeRecord]);
assert.equal(result, null);
});
test('URI record first, SP record second - SP returned', function() {
var result = nfcManager._getSmartPoster([uriRecord, smartPosterRecord]);
assert.deepEqual(result, smartPosterRecord);
});
test('MIME record first, SP record second - null returned', function() {
var result = nfcManager._getSmartPoster([mimeRecord, smartPosterRecord]);
assert.equal(result, null);
});
test('SP record only - SP record returned', function() {
var result = nfcManager._getSmartPoster([smartPosterRecord]);
assert.deepEqual(result, smartPosterRecord);
});
test('Array empty - null returned', function() {
var result = nfcManager._getSmartPoster([]);
assert.equal(result, null);
});
});
suite('_createNDEFActivityOptions', function() {
const NDEF_ACTIVITY_NAME = 'nfc-ndef-discovered';
test('URI tel -> dial number', function() {
var payload = { type: 'uri', uri: 'tel:012345678' };
var options = nfcManager._createNDEFActivityOptions(payload);
assert.deepEqual(options, {
name: 'dial',
data: {
type: 'webtelephony/number',
number: payload.uri.substring(4),
uri: payload.uri,
src: 'nfc'
}
});
});
test('URI mailto -> create new mail', function() {
var payload = { type: 'uri', uri: 'mailto:bugzilla-daemon@mozilla.org' };
var options = nfcManager._createNDEFActivityOptions(payload);
assert.deepEqual(options, {
name: 'new',
data: {
type: 'mail',
url: payload.uri,
src: 'nfc'
}
});
});
test('URI http(s) -> launch browser', function() {
var payload = { type: 'uri', uri: 'http://mozilla.org' };
var options = nfcManager._createNDEFActivityOptions(payload);
assert.deepEqual(options, {
name: 'view',
data: {
type: 'url',
url: payload.uri,
src: 'nfc'
}
});
});
test('Data-URI -> launch browser', function() {
var payload = { type: 'uri', uri: 'data:text/html,<b>Be bold</b>' };
var options = nfcManager._createNDEFActivityOptions(payload);
assert.deepEqual(options, {
name: 'view',
data: {
type: 'url',
url: payload.uri,
src: 'nfc'
}
});
});
test('URI other', function() {
var payload = { type: 'uri', uri: 'sip:bob@bob.com' };
var options = nfcManager._createNDEFActivityOptions(payload);
assert.deepEqual(options, {
name: NDEF_ACTIVITY_NAME,
data: {
type: 'uri',
uri: payload.uri
}
});
});
test('SmartPoster with http(s) -> launch browser', function() {
var payload = {
type: 'smartposter',
uri: 'http://mozilla.org',
text: {
en: 'Home of the Mozilla Project',
pl: 'Strona domowa projektu Mozilla'
}
};
var options = nfcManager._createNDEFActivityOptions(payload);
assert.deepEqual(options, {
name: 'view',
data: {
type: 'url',
text: payload.text,
url: 'http://mozilla.org',
src: 'nfc'
}
});
});
test('SmartPoster other URI', function() {
var payload = {
type: 'smartposter',
uri: 'sip:bob@bob.com',
text: {
en: 'Call me!',
pl: 'Zadzwoń do mnie!'
}
};
var options = nfcManager._createNDEFActivityOptions(payload);
assert.deepEqual(options, {
name: NDEF_ACTIVITY_NAME,
data: payload
});
});
test('text/vcard -> import contct', function() {
var payload = {
type: 'text/vcard',
blob: new Blob(['dummy'], {type: 'text/vcard'})
};
var options = nfcManager._createNDEFActivityOptions(payload);
assert.deepEqual(options, {
name: 'import',
data: payload
});
});
test('other payload', function() {
var payload = {
type: 'http://mozilla.org'
};
var options = nfcManager._createNDEFActivityOptions(payload);
assert.deepEqual(options, {
name: NDEF_ACTIVITY_NAME,
data: {
type: payload.type
}
});
});
test('no payload', function() {
var options = nfcManager._createNDEFActivityOptions(null);
assert.deepEqual(options, { name: NDEF_ACTIVITY_NAME, data: {} });
});
});
suite('_cleanP2PUI', function() {
test('removes "shrinking-sent" event listner', function() {
var stubRemoveListener = this.sinon.stub(window, 'removeEventListener');
var fakeListner = () => { return 'fake'; };
nfcManager._handleShrinkingSent = fakeListner;
nfcManager._cleanP2PUI();
assert.isTrue(stubRemoveListener.calledOnce);
assert.deepEqual(stubRemoveListener.firstCall.args,
['shrinking-sent', fakeListner]);
});
test('publishes "shrinking-stop" event', function() {
var stubPublish = this.sinon.stub(nfcManager, 'publish');
nfcManager._cleanP2PUI();
assert.isTrue(stubPublish.calledOnce);
assert.deepEqual(stubPublish.firstCall.args,
['shrinking-stop', nfcManager, true]);
});
});
suite('_initP2PUI', function() {
test('publishes "shrinking-start event"', function() {
// prevents registering event listener handler
this.sinon.stub(window, 'addEventListener');
var stubPublish = this.sinon.stub(nfcManager, 'publish');
nfcManager._initP2PUI();
assert.isTrue(stubPublish.calledOnce);
assert.deepEqual(stubPublish.firstCall.args,
['shrinking-start', nfcManager, true]);
});
test('adds "shrinking-sent" event listner', function() {
var stubAddListener = this.sinon.stub(window, 'addEventListener');
nfcManager._initP2PUI();
assert.isTrue(stubAddListener.calledOnce);
assert.deepEqual(stubAddListener.firstCall.args,
['shrinking-sent', nfcManager._handleShrinkingSent]);
});
test('"shrinking-sent" handler calls proper methods', function() {
var stubCleanP2PUI = this.sinon.stub(nfcManager, '_cleanP2PUI');
var stubDispatchP2P = this.sinon.stub(nfcManager,
'_dispatchP2PUserResponse');
nfcManager._initP2PUI();
window.dispatchEvent(new CustomEvent('shrinking-sent'));
assert.isTrue(stubCleanP2PUI.calledOnce, '_cleanP2PUI');
assert.isTrue(stubDispatchP2P.calledOnce, '_dispatchP2PUserResponse');
});
});
suite('_dispatchP2PUserResponse', function() {
test('calls proper mozNfc method', function() {
var stubNotifyAcceptedP2P = this.sinon.stub(MockNfc,
'notifyUserAcceptedP2P');
nfcManager._dispatchP2PUserResponse();
assert.isTrue(stubNotifyAcceptedP2P.withArgs(fakeAppConfig.manifestURL)
.calledOnce);
});
});
suite('_checkP2PRegistrations', function() {
test('calls proper mozNfc method', function() {
var stubCheckP2P = this.sinon.stub(MockNfc, 'checkP2PRegistration',
() => { return Promise.resolve(); });
nfcManager._checkP2PRegistration();
assert.isTrue(stubCheckP2P.withArgs(fakeAppConfig.manifestURL)
.calledOnce);
});
test('app registered onpeerready handler - success', function() {
// Setup Fake Promise to stub with:
var fakePromise = new MockPromise();
this.sinon.stub(MockNfc, 'checkP2PRegistration',
(manifest) => fakePromise);
var stubDispatchEvent = this.sinon.stub(window, 'dispatchEvent');
var spyAddEventListener = this.sinon.spy(window, 'addEventListener');
nfcManager._checkP2PRegistration();
fakePromise.mFulfillToValue(true);
stubDispatchEvent.getCall(0).calledWith({ type: 'shrinking-start',
bubbles: false });
assert.isTrue(spyAddEventListener.withArgs('shrinking-sent').calledOnce);
});
test('app registered onpeerready handler - success, ' +
'but sheets is in transitioning', function() {
// Setup Fake Promise to stub with:
var fakePromise = new MockPromise();
this.sinon.stub(MockNfc, 'checkP2PRegistration',
(manifest) => fakePromise);
var spyAddEventListener = this.sinon.spy(window, 'addEventListener');
this.sinon.stub(fakeApp, 'isSheetTransitioning').returns(true);
nfcManager._checkP2PRegistration();
fakePromise.mFulfillToValue(true);
assert.isFalse(spyAddEventListener.withArgs('shrinking-sent').calledOnce);
});
test('app registered onpeerready handler - success, ' +
'but app is in transitioning', function() {
// Setup Fake Promise to stub with:
var fakePromise = new MockPromise();
this.sinon.stub(MockNfc, 'checkP2PRegistration',
(manifest) => fakePromise);
var spyAddEventListener = this.sinon.spy(window, 'addEventListener');
this.sinon.stub(fakeApp, 'isTransitioning').returns(true);
nfcManager._checkP2PRegistration();
fakePromise.mFulfillToValue(true);
assert.isFalse(spyAddEventListener.withArgs('shrinking-sent').calledOnce);
});
test('app not registered for onpeerready event - error', function() {
// Setup Fake Promise to stub with:
var fakePromise = new MockPromise();
this.sinon.stub(MockNfc, 'checkP2PRegistration',
(manifestURL) => fakePromise);
var stubDispatchEvent = this.sinon.stub(window, 'dispatchEvent');
var spyRemoveEventListener = this.sinon.spy(window,
'removeEventListener');
nfcManager._checkP2PRegistration();
// Note: Error status is fired through the success code path.
fakePromise.mFulfillToValue(false);
stubDispatchEvent.getCall(0).calledWith({ type: 'shrinking-stop',
bubbles: false });
assert.isTrue(
spyRemoveEventListener.withArgs('shrinking-sent').calledOnce);
});
test('private browser landing page', function() {
var fakePromise = new MockPromise();
var stubCheckP2P = this.sinon.stub(MockNfc, 'checkP2PRegistration',
() => fakePromise);
MockService.mockQueryWith('getTopMostWindow',
new window.AppWindow(fakePrivateLandingPage));
this.sinon.stub(MockService.mockQueryWith('getTopMostWindow'),
'isPrivateBrowser').returns(true);
// Should not shrink on the landing page.
nfcManager._checkP2PRegistration();
assert.isTrue(stubCheckP2P.notCalled);
// Able to share pages after navigating.
MockService.mockQueryWith('getTopMostWindow').config.url =
'http://mozilla.org';
nfcManager._checkP2PRegistration();
assert.isTrue(stubCheckP2P.calledOnce);
});
test('browser with fullscreen', function() {
var fakePromise = new MockPromise();
var stubCheckP2P = this.sinon.stub(MockNfc, 'checkP2PRegistration',
() => fakePromise);
MockService.mockQueryWith('getTopMostWindow',
new window.AppWindow(fakeBrowserForFullscreen));
Object.defineProperty(document, 'mozFullScreen', {
configurable: true,
value: true
});
// Should not shrink when it is fullscreen.
nfcManager._checkP2PRegistration();
assert.isTrue(stubCheckP2P.notCalled);
this.sinon.stub(MockService.mockQueryWith('getTopMostWindow'),
'isBrowser').returns(false);
nfcManager._checkP2PRegistration();
assert.isTrue(stubCheckP2P.calledOnce);
Object.defineProperty(document, 'mozFullScreen', {
configurable: true,
value: false
});
});
});
});