Revision control

Copy as Markdown

Other Tools

/* Any copyright is dedicated to the Public Domain.
const { setTimeout } = ChromeUtils.importESModule(
);
var { GenericConvIMPrototype } = ChromeUtils.importESModule(
);
var _id = 0;
function Conversation(name) {
this._name = name;
this._observers = [];
this._date = Date.now() * 1000;
this.id = ++_id;
this.typingState = undefined;
}
Conversation.prototype = {
__proto__: GenericConvIMPrototype,
_account: {
imAccount: {
protocol: { name: "Fake Protocol" },
alias: "",
name: "Fake Account",
},
ERROR(e) {
throw e;
},
DEBUG() {},
},
setTypingState(newState) {
this.typingState = newState;
},
};
// ROT13, used as an example transformation.
function rot13(aString) {
return aString.replace(/[a-zA-Z]/g, function (c) {
return String.fromCharCode(
c.charCodeAt(0) + (c.toLowerCase() < "n" ? 1 : -1) * 13
);
});
}
// A test that cancels a message before it can be sent.
add_task(function test_cancel_send_message() {
const conv = new Conversation();
conv.dispatchMessage = function () {
ok(
false,
"The message should have been halted in the conversation service."
);
};
let sending = false;
conv.addObserver({
observe(aObject, aTopic) {
switch (aTopic) {
case "sending-message":
ok(
aObject.QueryInterface(Ci.imIOutgoingMessage),
"Wrong message type."
);
aObject.cancelled = true;
sending = true;
break;
case "new-text":
ok(
false,
"No other notification should be fired for a cancelled message."
);
break;
}
},
});
conv.sendMsg("Hi!");
ok(sending, "The sending-message notification was never fired.");
});
// A test that ensures protocols get a chance to prepare a message before
// sending and displaying.
add_task(function test_prpl_message_prep() {
const conv = new Conversation();
conv.dispatchMessage = function (aMsg) {
this.writeMessage("user", aMsg, { outgoing: true });
};
conv.prepareForSending = function (aMsg) {
ok(aMsg.QueryInterface(Ci.imIOutgoingMessage), "Wrong message type.");
equal(aMsg.message, msg, "Expected the original message.");
prepared = true;
return [prefix + aMsg.message];
};
conv.prepareForDisplaying = function (aMsg) {
equal(aMsg.displayMessage, prefix + msg, "Expected the prefixed message.");
aMsg.displayMessage = aMsg.displayMessage.slice(prefix.length);
};
const msg = "Hi!";
const prefix = "test> ";
let prepared = false;
let receivedMsg = false;
conv.addObserver({
observe(aObject, aTopic) {
if (aTopic === "preparing-message") {
equal(aObject.message, msg, "Expected the original message");
} else if (aTopic === "sending-message") {
equal(aObject.message, prefix + msg, "Expected the prefixed message.");
} else if (aTopic === "new-text") {
ok(aObject.QueryInterface(Ci.prplIMessage), "Wrong message type.");
ok(prepared, "The message was not prepared before sending.");
equal(aObject.message, prefix + msg, "Expected the prefixed message.");
receivedMsg = true;
aObject.displayMessage = aObject.originalMessage;
conv.prepareForDisplaying(aObject);
equal(aObject.displayMessage, msg, "Expected the original message");
}
},
});
conv.sendMsg(msg);
ok(receivedMsg, "The new-text notification was never fired.");
});
// A test that ensures protocols can split messages before they are sent.
add_task(function test_split_message_before_sending() {
let msgCount = 0;
let prepared = false;
const msg = "This is a looo\nooong message.\nThis one is short.";
const msgs = msg.split("\n");
const conv = new Conversation();
conv.dispatchMessage = function (aMsg) {
equal(aMsg, msgs[msgCount++], "Sending an unexpected message.");
};
conv.prepareForSending = function (aMsg) {
ok(aMsg.QueryInterface(Ci.imIOutgoingMessage), "Wrong message type.");
prepared = true;
return aMsg.message.split("\n");
};
conv.sendMsg(msg);
ok(prepared, "Message wasn't prepared for sending.");
equal(msgCount, 3, "Not enough messages were sent.");
});
add_task(function test_removeMessage() {
let didRemove = false;
const conv = new Conversation();
conv.addObserver({
observe(subject, topic, data) {
if (topic === "remove-text") {
equal(data, "foo");
didRemove = true;
}
},
});
conv.removeMessage("foo");
ok(didRemove);
});
add_task(function test_sendTyping() {
const roomStub = new Conversation();
Services.prefs.setBoolPref("purple.conversations.im.send_typing", false);
// Nothing happens until the conversation supports typing & the pref is enabled.
let result = roomStub.sendTyping("lorem ipsum");
ok(!roomStub._typingTimer, "Typing is disabled");
equal(
result,
Ci.prplIConversation.NO_TYPING_LIMIT,
"Default to no typing limit"
);
equal(roomStub.typingState, undefined, "Typing state is uninitialized");
roomStub.supportTypingNotifications = true;
result = roomStub.sendTyping("lorem ipsum");
ok(!roomStub._typingTimer, "Typing is disabled via pref");
equal(
result,
Ci.prplIConversation.NO_TYPING_LIMIT,
"Default to no typing limit 2"
);
equal(roomStub.typingState, undefined, "Typing state is unmodified");
Services.prefs.setBoolPref("purple.conversations.im.send_typing", true);
// A message changes the state to typing.
result = roomStub.sendTyping("lorem ipsum");
ok(roomStub._typingTimer, "Typing is enabled and a timer is configured");
equal(
result,
Ci.prplIConversation.NO_TYPING_LIMIT,
"Default to no typing limit 3"
);
equal(roomStub.typingState, Ci.prplIConvIM.TYPING, "The user is typing");
// Clearing the input resets to not typing.
result = roomStub.sendTyping("");
ok(!roomStub._typingTimer, "Typing timer is cancelled and reset");
equal(
result,
Ci.prplIConversation.NO_TYPING_LIMIT,
"Default to no typing limit 4"
);
equal(
roomStub.typingState,
Ci.prplIConvIM.NOT_TYPING,
"The user is no longer typing"
);
roomStub.unInit();
});
add_task(function test_cancelTypingTimer() {
const roomStub = {
_typingTimer: setTimeout(() => {}, 10000), // eslint-disable-line mozilla/no-arbitrary-setTimeout
};
Conversation.prototype._cancelTypingTimer.call(roomStub);
ok(!roomStub._typingTimer, "Typing timer is cancelled and reset");
});
add_task(function test_finishedComposing() {
const roomStub = new Conversation();
roomStub.finishedComposing();
equal(roomStub.typingState, undefined, "Typing is disabled");
roomStub.supportTypingNotifications = true;
roomStub.finishedComposing();
equal(
roomStub.typingState,
Ci.prplIConvIM.TYPED,
"The user has left a message in the window"
);
});