blob: 979c7c973e1d5a42d060ee9cb0f2d27ed3e99690 [file] [log] [blame]
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
describe('android exec.processMessages', function () {
var cordova = require('cordova');
var exec = require('cordova/android/exec');
var nativeApiProvider = require('cordova/android/nativeapiprovider');
var origNativeApi = nativeApiProvider.get();
var nativeApi = {
exec: jasmine.createSpy('nativeApi.exec'),
retrieveJsMessages: jasmine.createSpy('nativeApi.retrieveJsMessages')
};
beforeEach(function () {
nativeApi.exec.calls.reset();
nativeApi.retrieveJsMessages.calls.reset();
// Avoid a log message warning about the lack of _nativeApi.
exec.setJsToNativeBridgeMode(exec.jsToNativeModes.PROMPT);
nativeApiProvider.set(nativeApi);
/* eslint-disable no-undef */
var origPrompt = typeof prompt === 'undefined' ? undefined : prompt;
prompt = function () { return 1234; };
exec.init();
prompt = origPrompt;
/* eslint-enable no-undef */
});
afterEach(function () {
nativeApiProvider.set(origNativeApi);
cordova.callbacks = {};
});
function createCallbackMessage (success, keepCallback, status, callbackId, encodedPayload) {
var ret = '';
ret += success ? 'S' : 'F';
ret += keepCallback ? '1' : '0';
ret += status;
ret += ' ' + callbackId;
ret += ' ' + encodedPayload;
ret = ret.length + ' ' + ret;
return ret;
}
describe('exec', function () {
it('Test#001 : should process messages in order even when called recursively', function (done) {
var firstCallbackId = null;
var callCount = 0;
nativeApi.exec.and.callFake(function (secret, service, action, callbackId, argsJson) {
expect(secret).toBe(1234);
++callCount;
if (callCount === 1) {
firstCallbackId = callbackId;
return '';
}
if (callCount === 2) {
return createCallbackMessage(true, false, 1, firstCallbackId, 't') +
createCallbackMessage(true, false, 1, callbackId, 'stwo');
}
return createCallbackMessage(true, false, 1, callbackId, 'sthree');
});
var win2Called = false;
var winSpy3 = jasmine.createSpy('win3').and.callFake(arg => {
expect(arg).toBe('three');
done();
});
function win1 (value) {
expect(value).toBe(true);
exec(winSpy3, null, 'Service', 'action', []);
expect(win2Called).toBe(false, 'win1 should finish before win2 starts');
}
function win2 (value) {
win2Called = true;
expect(value).toBe('two');
expect(winSpy3).not.toHaveBeenCalled();
}
exec(win1, null, 'Service', 'action', []);
exec(win2, null, 'Service', 'action', []);
});
it('Test#002 : should process messages asynchronously', function (done) {
nativeApi.exec.and.callFake(function (secret, service, action, callbackId, argsJson) {
expect(secret).toBe(1234);
return createCallbackMessage(true, false, 1, callbackId, 'stwo');
});
var winSpy = jasmine.createSpy('win').and.callFake(done);
exec(winSpy, null, 'Service', 'action', []);
expect(winSpy).not.toHaveBeenCalled();
});
});
describe('processMessages', function () {
var origCallbackFromNative = cordova.callbackFromNative;
var callbackSpy = jasmine.createSpy('callbackFromNative');
beforeEach(function () {
callbackSpy.calls.reset();
cordova.callbackFromNative = callbackSpy;
});
afterEach(function () {
cordova.callbackFromNative = origCallbackFromNative;
});
function performExecAndReturn (messages) {
nativeApi.exec.and.callFake(function (secret, service, action, callbackId, argsJson) {
return messages;
});
exec(null, null, 'Service', 'action', []);
}
function performExecAndAwaitSingleCallback (messages) {
performExecAndReturn(messages);
return new Promise(resolve => callbackSpy.and.callFake(resolve));
}
it('Test#003 : should handle payloads of false', function () {
var messages = createCallbackMessage(true, true, 1, 'id', 'f');
return performExecAndAwaitSingleCallback(messages).then(() => {
expect(callbackSpy).toHaveBeenCalledWith('id', true, 1, [false], true);
});
});
it('Test#004 : should handle payloads of true', function () {
var messages = createCallbackMessage(true, true, 1, 'id', 't');
return performExecAndAwaitSingleCallback(messages).then(() => {
expect(callbackSpy).toHaveBeenCalledWith('id', true, 1, [true], true);
});
});
it('Test#005 : should handle payloads of null', function () {
var messages = createCallbackMessage(true, true, 1, 'id', 'N');
return performExecAndAwaitSingleCallback(messages).then(() => {
expect(callbackSpy).toHaveBeenCalledWith('id', true, 1, [null], true);
});
});
it('Test#006 : should handle payloads of numbers', function () {
var messages = createCallbackMessage(true, true, 1, 'id', 'n-3.3');
return performExecAndAwaitSingleCallback(messages).then(() => {
expect(callbackSpy).toHaveBeenCalledWith('id', true, 1, [-3.3], true);
});
});
it('Test#007 : should handle payloads of strings', function () {
var messages = createCallbackMessage(true, true, 1, 'id', 'sHello world');
return performExecAndAwaitSingleCallback(messages).then(() => {
expect(callbackSpy).toHaveBeenCalledWith('id', true, 1, ['Hello world'], true);
});
});
it('Test#008 : should handle payloads of JSON objects', function () {
var messages = createCallbackMessage(true, true, 1, 'id', '{"a":1}');
return performExecAndAwaitSingleCallback(messages).then(() => {
expect(callbackSpy).toHaveBeenCalledWith('id', true, 1, [{a: 1}], true);
});
});
it('Test#009 : should handle payloads of JSON arrays', function () {
var messages = createCallbackMessage(true, true, 1, 'id', '[1]');
return performExecAndAwaitSingleCallback(messages).then(() => {
expect(callbackSpy).toHaveBeenCalledWith('id', true, 1, [[1]], true);
});
});
it('Test#010 : should handle other callback opts', function () {
var messages = createCallbackMessage(false, false, 3, 'id', 'sfoo');
return performExecAndAwaitSingleCallback(messages).then(() => {
expect(callbackSpy).toHaveBeenCalledWith('id', false, 3, ['foo'], false);
});
});
it('Test#011 : should handle multiple messages', function (done) {
var message1 = createCallbackMessage(false, false, 3, 'id', 'sfoo');
var message2 = createCallbackMessage(true, true, 1, 'id', 'f');
var messages = message1 + message2;
callbackSpy.and.callFake(() => {
// need to wait for ALL the callbacks before we check our expects
if (callbackSpy.calls.count() < 2) return;
expect(callbackSpy).toHaveBeenCalledWith('id', false, 3, ['foo'], false);
expect(callbackSpy).toHaveBeenCalledWith('id', true, 1, [false], true);
done();
});
performExecAndReturn(messages);
});
it('Test#012 : should poll for more messages when hitting an *', function (done) {
var message1 = createCallbackMessage(false, false, 3, 'id', 'sfoo');
var message2 = createCallbackMessage(true, true, 1, 'id', 'f');
nativeApi.retrieveJsMessages.and.callFake(function () {
expect(callbackSpy).toHaveBeenCalledWith('id', false, 3, ['foo'], false);
return message2;
});
callbackSpy.and.callFake(() => {
if (callbackSpy.calls.count() < 2) return;
expect(callbackSpy).toHaveBeenCalledWith('id', true, 1, [false], true);
done();
});
performExecAndReturn(message1 + '*');
});
it('Test#013 : should call callbacks in order when one callback enqueues another.', function (done) {
var message1 = createCallbackMessage(false, false, 3, 'id', 'scall1');
var message2 = createCallbackMessage(false, false, 3, 'id', 'scall2');
var message3 = createCallbackMessage(false, false, 3, 'id', 'scall3');
callbackSpy.and.callFake(() => {
if (callbackSpy.calls.count() === 1) {
performExecAndReturn(message3);
} else if (callbackSpy.calls.count() === 3) {
// need to wait for ALL the callbacks before we check our expects
expect(callbackSpy.calls.argsFor(0)).toEqual(['id', false, 3, ['call1'], false]);
expect(callbackSpy.calls.argsFor(1)).toEqual(['id', false, 3, ['call2'], false]);
expect(callbackSpy.calls.argsFor(2)).toEqual(['id', false, 3, ['call3'], false]);
done();
}
});
performExecAndReturn(message1 + message2);
});
});
});