Bug 736710 - Part 4: Marionette unit tests for Voicemail API. r=vicamo

This commit is contained in:
Marshall Culpepper 2012-07-19 11:27:35 +08:00
parent 1000d1405e
commit c864ffabd4
4 changed files with 399 additions and 0 deletions

View File

@ -16,3 +16,4 @@ qemu = true
#[test_outgoing_busy.js]
#expectedfailure = true
[test_outgoing_reject.js]
[test_voicemail_statuschanged.py]

View File

@ -0,0 +1,149 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Only bring in what we need from ril_worker/RadioInterfaceLayer here. Reusing
// that code turns out to be a nightmare, so there is some code duplication.
let PDUBuilder = {
toHexString: function toHexString(n, length) {
let str = n.toString(16);
if (str.length < length) {
for (let i = 0; i < length - str.length; i++) {
str = "0" + str;
}
}
return str.toUpperCase();
},
writeUint16: function writeUint16(value) {
this.buf += (value & 0xff).toString(16).toUpperCase();
this.buf += ((value >> 8) & 0xff).toString(16).toUpperCase();
},
writeHexOctet: function writeHexOctet(octet) {
this.buf += this.toHexString(octet, 2);
},
writeSwappedNibbleBCD: function writeSwappedNibbleBCD(data) {
data = data.toString();
let zeroCharCode = '0'.charCodeAt(0);
for (let i = 0; i < data.length; i += 2) {
let low = data.charCodeAt(i) - zeroCharCode;
let high;
if (i + 1 < data.length) {
high = data.charCodeAt(i + 1) - zeroCharCode;
} else {
high = 0xF;
}
this.writeHexOctet((high << 4) | low);
}
},
writeStringAsSeptets: function writeStringAsSeptets(message,
paddingBits,
langIndex,
langShiftIndex)
{
const langTable = PDU_NL_LOCKING_SHIFT_TABLES[langIndex];
const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex];
let dataBits = paddingBits;
let data = 0;
for (let i = 0; i < message.length; i++) {
let septet = langTable.indexOf(message[i]);
if (septet == PDU_NL_EXTENDED_ESCAPE) {
continue;
}
if (septet >= 0) {
data |= septet << dataBits;
dataBits += 7;
} else {
septet = langShiftTable.indexOf(message[i]);
if (septet == -1) {
throw new Error(message[i] + " not in 7 bit alphabet "
+ langIndex + ":" + langShiftIndex + "!");
}
if (septet == PDU_NL_RESERVED_CONTROL) {
continue;
}
data |= PDU_NL_EXTENDED_ESCAPE << dataBits;
dataBits += 7;
data |= septet << dataBits;
dataBits += 7;
}
for (; dataBits >= 8; dataBits -= 8) {
this.writeHexOctet(data & 0xFF);
data >>>= 8;
}
}
if (dataBits != 0) {
this.writeHexOctet(data & 0xFF);
}
},
buildAddress: function buildAddress(address) {
let addressFormat = PDU_TOA_ISDN; // 81
if (address[0] == '+') {
addressFormat = PDU_TOA_INTERNATIONAL | PDU_TOA_ISDN; // 91
address = address.substring(1);
}
this.buf = "";
this.writeHexOctet(address.length);
this.writeHexOctet(addressFormat);
this.writeSwappedNibbleBCD(address);
return this.buf;
},
// assumes 7 bit encoding
buildUserData: function buildUserData(options) {
let headerLength = 0;
this.buf = "";
if (options.headers) {
for each (let header in options.headers) {
headerLength += 2; // id + length octets
if (header.octets) {
headerLength += header.octets.length;
}
};
}
let encodedBodyLength = options.body.length;
let headerOctets = (headerLength ? headerLength + 1 : 0);
let paddingBits;
let userDataLengthInSeptets;
let headerSeptets = Math.ceil(headerOctets * 8 / 7);
userDataLengthInSeptets = headerSeptets + encodedBodyLength;
paddingBits = headerSeptets * 7 - headerOctets * 8;
this.writeHexOctet(userDataLengthInSeptets);
if (options.headers) {
this.writeHexOctet(headerLength);
for each (let header in options.headers) {
this.writeHexOctet(header.id);
this.writeHexOctet(header.length);
if (header.octets) {
for each (let octet in header.octets) {
this.writeHexOctet(octet);
}
}
}
}
this.writeStringAsSeptets(options.body, paddingBits,
PDU_NL_IDENTIFIER_DEFAULT,
PDU_NL_IDENTIFIER_DEFAULT);
return this.buf;
}
};

View File

@ -0,0 +1,229 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
const WHITELIST_PREF = "dom.voicemail.whitelist";
let uriPrePath = window.location.protocol + "//" + window.location.host;
SpecialPowers.setCharPref(WHITELIST_PREF, uriPrePath);
let voicemail = window.navigator.mozVoicemail;
ok(voicemail instanceof MozVoicemail);
is(voicemail.status, null);
function sendIndicatorPDU(pdu, listener, nextTest) {
let smsCommand = "sms pdu " + pdu;
let commandCompleted = false;
let sawEvent = false;
voicemail.addEventListener("statuschanged", function statusChanged(event) {
voicemail.removeEventListener("statuschanged", statusChanged);
try {
listener(event);
} catch (e) {
ok(false, String(e));
}
sawEvent = true;
if (commandCompleted) {
nextTest();
}
});
log("-> " + smsCommand);
runEmulatorCmd(smsCommand, function(result) {
log("<- " + result);
is(result[0], "OK");
commandCompleted = true;
if (sawEvent) {
nextTest();
}
});
}
// TODO: Add tests for store/discard once they are implemented
// See RadioInterfaceLayer.js / Bug #768441
function isVoicemailStatus(status) {
is(voicemail.status.hasMessages, status.hasMessages);
is(voicemail.status.messageCount, status.messageCount);
is(voicemail.status.returnNumber, status.returnNumber);
is(voicemail.status.returnMessage, status.returnMessage);
}
const MWI_PDU_PREFIX = "0000";
const MWI_PDU_UDH_PREFIX = "0040";
const MWI_PID_DEFAULT = "00";
const MWI_PID_RETURN_CALL_MSG = "5F";
const MWI_DCS_DATA_MSG = "F0";
const MWI_DCS_DISCARD_INACTIVE = "C0";
const MWI_DCS_DISCARD_ACTIVE = "C8";
const MWI_TIMESTAMP = "00000000000000";
const MWI_LEVEL1_SENDER = "+15125551234";
const MWI_LEVEL1_PDU_ADDRESS = PDUBuilder.buildAddress(MWI_LEVEL1_SENDER);
const MWI_DEFAULT_BODY = "1 new voicemail";
const MWI_UD_DEFAULT = PDUBuilder.buildUserData({
body: MWI_DEFAULT_BODY
});
// Level 1 Message Waiting is just a return call message
const MWI_LEVEL1_PDU =
MWI_PDU_PREFIX +
MWI_LEVEL1_PDU_ADDRESS +
MWI_PID_RETURN_CALL_MSG +
MWI_DCS_DATA_MSG +
MWI_TIMESTAMP +
MWI_UD_DEFAULT;
function testLevel1Indicator() {
function onLevel1Indicator(event) {
let status = event.status;
ok(status instanceof MozVoicemailStatus);
is(status.hasMessages, true);
is(status.messageCount, status.MESSAGE_COUNT_UNKNOWN);
is(status.returnNumber, MWI_LEVEL1_SENDER);
is(status.returnMessage, MWI_DEFAULT_BODY);
isVoicemailStatus(status);
}
sendIndicatorPDU(MWI_LEVEL1_PDU, onLevel1Indicator, testLevel2DiscardActive);
}
const MWI_LEVEL2_SENDER = "+15125551235";
const MWI_LEVEL2_PDU_ADDRESS = PDUBuilder.buildAddress(MWI_LEVEL2_SENDER);
const MWI_LEVEL2_DISCARD_ACTIVE_PDU =
MWI_PDU_PREFIX +
MWI_LEVEL2_PDU_ADDRESS +
MWI_PID_DEFAULT +
MWI_DCS_DISCARD_ACTIVE +
MWI_TIMESTAMP +
MWI_UD_DEFAULT;
function testLevel2DiscardActive() {
function onLevel2Active(event) {
let status = event.status;
ok(status instanceof MozVoicemailStatus);
is(status.hasMessages, true);
is(status.messageCount, status.MESSAGE_COUNT_UNKNOWN);
is(status.returnNumber, MWI_LEVEL2_SENDER);
is(status.returnMessage, MWI_DEFAULT_BODY);
isVoicemailStatus(status);
}
sendIndicatorPDU(MWI_LEVEL2_DISCARD_ACTIVE_PDU,
onLevel2Active,
testLevel2DiscardInactive);
}
const MWI_LEVEL2_DISCARD_INACTIVE_PDU =
MWI_PDU_PREFIX +
MWI_LEVEL2_PDU_ADDRESS +
MWI_PID_DEFAULT +
MWI_DCS_DISCARD_INACTIVE +
MWI_TIMESTAMP +
MWI_UD_DEFAULT;
function testLevel2DiscardInactive() {
function onLevel2Inactive(event) {
let status = event.status;
ok(status instanceof MozVoicemailStatus);
is(status.hasMessages, false);
is(status.messageCount, 0);
is(status.returnNumber, MWI_LEVEL2_SENDER);
is(status.returnMessage, MWI_DEFAULT_BODY);
isVoicemailStatus(status);
}
sendIndicatorPDU(MWI_LEVEL2_DISCARD_INACTIVE_PDU,
onLevel2Inactive,
testLevel3DiscardActive);
}
// Tests for Level 3 MWI with a message count in the User Data Header
const MWI_LEVEL3_SENDER = "+15125551236";
const MWI_LEVEL3_PDU_ADDRESS = PDUBuilder.buildAddress(MWI_LEVEL3_SENDER);
const MWI_LEVEL3_ACTIVE_UDH_MSG_COUNT = 3;
const MWI_LEVEL3_ACTIVE_BODY = "3 new voicemails";
const MWI_LEVEL3_ACTIVE_UD = PDUBuilder.buildUserData({
headers: [{
id: PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION,
length: 2,
octets: [
PDU_MWI_STORE_TYPE_DISCARD,
MWI_LEVEL3_ACTIVE_UDH_MSG_COUNT
]
}],
body: MWI_LEVEL3_ACTIVE_BODY
});
const MWI_LEVEL3_DISCARD_ACTIVE_PDU =
MWI_PDU_UDH_PREFIX +
MWI_LEVEL3_PDU_ADDRESS +
MWI_PID_DEFAULT +
MWI_DCS_DISCARD_ACTIVE +
MWI_TIMESTAMP +
MWI_LEVEL3_ACTIVE_UD;
function testLevel3DiscardActive() {
function onLevel3Active(event) {
let status = event.status;
ok(status instanceof MozVoicemailStatus);
is(status.hasMessages, true);
is(status.messageCount, MWI_LEVEL3_ACTIVE_UDH_MSG_COUNT);
is(status.returnNumber, MWI_LEVEL3_SENDER);
is(status.returnMessage, MWI_LEVEL3_ACTIVE_BODY);
isVoicemailStatus(status);
}
sendIndicatorPDU(MWI_LEVEL3_DISCARD_ACTIVE_PDU,
onLevel3Active,
testLevel3DiscardInactive);
}
const MWI_LEVEL3_INACTIVE_BODY = "No unread voicemails";
const MWI_LEVEL3_INACTIVE_UD = PDUBuilder.buildUserData({
headers: [{
id: PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION,
length: 2,
octets: [
PDU_MWI_STORE_TYPE_DISCARD,
0 // messageCount
]
}],
body: MWI_LEVEL3_INACTIVE_BODY
});
const MWI_LEVEL3_DISCARD_INACTIVE_PDU =
MWI_PDU_UDH_PREFIX +
MWI_LEVEL3_PDU_ADDRESS +
MWI_PID_DEFAULT +
MWI_DCS_DISCARD_ACTIVE +
MWI_TIMESTAMP +
MWI_LEVEL3_INACTIVE_UD;
function testLevel3DiscardInactive() {
function onLevel3Inactive(event) {
let status = event.status;
ok(status instanceof MozVoicemailStatus);
is(status.hasMessages, false);
is(status.messageCount, 0);
is(status.returnNumber, MWI_LEVEL3_SENDER);
is(status.returnMessage, MWI_LEVEL3_INACTIVE_BODY);
isVoicemailStatus(status);
}
sendIndicatorPDU(MWI_LEVEL3_DISCARD_INACTIVE_PDU, onLevel3Inactive, cleanUp);
}
function cleanUp() {
SpecialPowers.clearUserPref(WHITELIST_PREF);
finish();
}
testLevel1Indicator();

View File

@ -0,0 +1,20 @@
from marionette_test import MarionetteTestCase
import os
class TestVoicemailStatusChanged(MarionetteTestCase):
def testStatusChanged(self):
this_dir = os.path.abspath(os.path.dirname(__file__))
system_gonk_dir = os.path.abspath(os.path.join(this_dir,
os.path.pardir, os.path.pardir, os.path.pardir, "system", "gonk"))
ril_consts_path = os.path.join(system_gonk_dir, "ril_consts.js")
self.marionette.import_script(ril_consts_path)
pdu_builder_path = os.path.join(this_dir, "pdu_builder.js")
self.marionette.import_script(pdu_builder_path)
test_path = os.path.join(this_dir, "test_voicemail_statuschanged.js")
test = open(test_path, "r").read()
self.marionette.set_script_timeout(30000)
self.marionette.execute_async_script(test)