summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/news/test/unit/test_internalUris.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/news/test/unit/test_internalUris.js')
-rw-r--r--comm/mailnews/news/test/unit/test_internalUris.js305
1 files changed, 305 insertions, 0 deletions
diff --git a/comm/mailnews/news/test/unit/test_internalUris.js b/comm/mailnews/news/test/unit/test_internalUris.js
new file mode 100644
index 0000000000..4be0402f0e
--- /dev/null
+++ b/comm/mailnews/news/test/unit/test_internalUris.js
@@ -0,0 +1,305 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Tests internal URIs generated by various methods in the code base.
+ * If you manually generate a news URI somewhere, please add it to this test.
+ */
+
+Cu.importGlobalProperties(["crypto"]);
+
+/* import-globals-from ../../../test/resources/alertTestUtils.js */
+load("../../../resources/alertTestUtils.js");
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+var { PromiseTestUtils } = ChromeUtils.import(
+ "resource://testing-common/mailnews/PromiseTestUtils.jsm"
+);
+var { PromiseUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/PromiseUtils.sys.mjs"
+);
+
+var daemon, localserver, server;
+
+var kCancelArticle =
+ "From: fake@acme.invalid\n" +
+ "Newsgroups: test.filter\n" +
+ "Subject: cancel <4@regular.invalid>\n" +
+ "References: <4@regular.invalid>\n" +
+ "Control: cancel <4@regular.invalid>\n" +
+ "MIME-Version: 1.0\n" +
+ "Content-Type: text/plain\n" +
+ "\n" +
+ "This message was cancelled from within ";
+
+var dummyMsgWindow;
+
+add_setup(function setupTest() {
+ registerAlertTestUtils();
+
+ daemon = setupNNTPDaemon();
+ server = makeServer(NNTP_RFC2980_handler, daemon);
+ server.start();
+ localserver = setupLocalServer(server.port);
+
+ // Set up an identity for posting.
+ let identity = MailServices.accounts.createIdentity();
+ identity.fullName = "Normal Person";
+ identity.email = "fake@acme.invalid";
+ MailServices.accounts.FindAccountForServer(localserver).addIdentity(identity);
+
+ dummyMsgWindow = new DummyMsgWindow();
+});
+
+add_task(async function test_newMsgs() {
+ // This tests nsMsgNewsFolder::GetNewsMessages via getNewMessages.
+ let folder = localserver.rootFolder.getChildNamed("test.filter");
+ Assert.equal(folder.getTotalMessages(false), 0);
+ let urlListener = new PromiseTestUtils.PromiseUrlListener();
+ folder.getNewMessages(null, urlListener);
+ await urlListener.promise;
+ Assert.equal(folder.getTotalMessages(false), 8);
+});
+
+add_task(async function test_cancel() {
+ // This tests nsMsgNewsFolder::CancelMessage.
+ let folder = localserver.rootFolder.getChildNamed("test.filter");
+ let db = folder.msgDatabase;
+ let hdr = db.getMsgHdrForKey(4);
+
+ folder.QueryInterface(Ci.nsIMsgNewsFolder).cancelMessage(hdr, dummyMsgWindow);
+ await dummyMsgWindow.promise;
+
+ // Reset promise state.
+ dummyMsgWindow.deferPromise();
+
+ Assert.equal(folder.getTotalMessages(false), 7);
+
+ // Check the content of the CancelMessage itself.
+ let article = daemon.getGroup("test.filter")[9];
+ // Since the cancel message includes the brand name (Daily, Thunderbird), we
+ // only check the beginning of the string.
+ Assert.ok(article.fullText.startsWith(kCancelArticle));
+});
+
+function generateLongArticle() {
+ // After converting to base64, the message body will be 65536 * 4 = 256KB.
+ let arr = new Uint8Array(65536);
+ crypto.getRandomValues(arr);
+ return `Date: Mon, 23 Jun 2008 19:58:07 +0400
+From: Normal Person <fake@acme.invalid>
+MIME-Version: 1.0
+Subject: Odd Subject
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 7bit
+Message-ID: <2@regular.invalid>
+
+${btoa(arr)}
+${btoa(arr)}
+${btoa(arr)}
+`;
+}
+
+add_task(async function test_fetchMessage() {
+ // Replace the second article with a large message.
+ daemon.addArticleToGroup(
+ new NewsArticle(generateLongArticle()),
+ "test.filter",
+ 2
+ );
+
+ // Tests nsNntpService::CreateMessageIDURL via FetchMessage.
+ let streamListener = new PromiseTestUtils.PromiseStreamListener();
+ let urlListener = new PromiseTestUtils.PromiseUrlListener();
+ let folder = localserver.rootFolder.getChildNamed("test.filter");
+ MailServices.nntp.fetchMessage(folder, 2, null, streamListener, urlListener);
+ await urlListener.promise;
+ let data = await streamListener.promise;
+ // To point out that the streamListener Promise shouldn't reject.
+ Assert.ok(data);
+});
+
+add_task(async function test_fetchMessageNoStreamListener() {
+ // Tests nsNntpService::CreateMessageIDURL via FetchMessage.
+ let streamListener = null;
+ let urlListener = new PromiseTestUtils.PromiseUrlListener();
+ let folder = localserver.rootFolder.getChildNamed("test.filter");
+ MailServices.nntp.fetchMessage(folder, 2, null, streamListener, urlListener);
+ await urlListener.promise;
+});
+
+add_task(async function test_search() {
+ // This tests nsNntpService::Search.
+ let folder = localserver.rootFolder.getChildNamed("test.filter");
+ var searchSession = Cc[
+ "@mozilla.org/messenger/searchSession;1"
+ ].createInstance(Ci.nsIMsgSearchSession);
+ searchSession.addScopeTerm(Ci.nsMsgSearchScope.news, folder);
+
+ let searchTerm = searchSession.createTerm();
+ searchTerm.attrib = Ci.nsMsgSearchAttrib.Subject;
+ let value = searchTerm.value;
+ value.str = "First";
+ searchTerm.value = value;
+ searchTerm.op = Ci.nsMsgSearchOp.Contains;
+ searchTerm.booleanAnd = false;
+ searchSession.appendTerm(searchTerm);
+
+ let hitCount;
+ let searchListener = new PromiseTestUtils.PromiseSearchNotify(searchSession, {
+ onSearchHit() {
+ hitCount++;
+ },
+ onNewSearch() {
+ hitCount = 0;
+ },
+ });
+
+ searchSession.search(null);
+ await searchListener.promise;
+
+ Assert.equal(hitCount, 1);
+});
+
+add_task(async function test_grouplist() {
+ // This tests nsNntpService::GetListOfGroupsOnServer.
+ let subserver = localserver.QueryInterface(Ci.nsISubscribableServer);
+ let subscribablePromise = PromiseUtils.defer();
+ let subscribeListener = {
+ OnDonePopulating() {
+ subscribablePromise.resolve();
+ },
+ };
+ subserver.subscribeListener = subscribeListener;
+
+ function enumGroups(rootUri) {
+ let hierarchy = subserver.getChildURIs(rootUri);
+ let groups = [];
+ for (let name of hierarchy) {
+ if (subserver.isSubscribable(name)) {
+ groups.push(name);
+ }
+ if (subserver.hasChildren(name)) {
+ groups = groups.concat(enumGroups(name));
+ }
+ }
+ return groups;
+ }
+
+ MailServices.nntp.getListOfGroupsOnServer(localserver, null, false);
+ await subscribablePromise.promise;
+
+ let groups = enumGroups("");
+ Assert.equal(groups.length, Object.keys(daemon._groups).length);
+ for (let group in daemon._groups) {
+ Assert.ok(groups.includes(group));
+ }
+
+ // First node in the group list, even though it is not subscribable,
+ // parent of "test.empty" group.
+ Assert.equal(subserver.getFirstChildURI(""), "test");
+
+ // Release reference, somehow impedes GC of 'subserver'.
+ subserver.subscribeListener = null;
+});
+
+add_task(async function test_postMessage() {
+ // This tests nsNntpService::SetUpNntpUrlForPosting via PostMessage.
+ let urlListener = new PromiseTestUtils.PromiseUrlListener();
+ MailServices.nntp.postMessage(
+ do_get_file("postings/post2.eml"),
+ "misc.test",
+ localserver.key,
+ urlListener,
+ null
+ );
+ await urlListener.promise;
+ Assert.equal(daemon.getGroup("misc.test").keys.length, 1);
+});
+
+// Not tested because it requires UI, and this is insufficient, I think.
+// function test_forwardInline() {
+// // This tests mime_parse_stream_complete via forwarding inline
+// let folder = localserver.rootFolder.getChildNamed("test.filter");
+// let hdr = folder.msgDatabase.getMsgHdrForKey(1);
+// MailServices.compose.forwardMessage("a@b.invalid", hdr, null,
+// localserver, Ci.nsIMsgComposeService.kForwardInline);
+// }
+
+add_task(async function test_escapedName() {
+ // This does a few tests to make sure our internal URIs work for newsgroups
+ // with names that need escaping.
+ let evilName = "test.malformed&name";
+ daemon.addGroup(evilName);
+ daemon.addArticle(make_article(do_get_file("postings/bug670935.eml")));
+ localserver.subscribeToNewsgroup(evilName);
+
+ // Can we access it?
+ let folder = localserver.rootFolder.getChildNamed(evilName);
+ let newMessageUrlListener = new PromiseTestUtils.PromiseUrlListener();
+ folder.getNewMessages(null, newMessageUrlListener);
+ await newMessageUrlListener.promise;
+
+ // If we get here, we didn't crash--newsgroups unescape properly.
+ // Load a message, to test news-message: URI unescaping.
+ let streamlistener = new PromiseTestUtils.PromiseStreamListener();
+ let fetchMessageUrlListener = new PromiseTestUtils.PromiseUrlListener();
+ MailServices.nntp.fetchMessage(
+ folder,
+ 1,
+ null,
+ streamlistener,
+ fetchMessageUrlListener
+ );
+ await fetchMessageUrlListener.promise;
+ let data = await streamlistener.promise;
+ // To point out that the streamListener Promise shouldn't reject.
+ Assert.ok(data);
+});
+
+add_task(function cleanUp() {
+ localserver.closeCachedConnections();
+});
+
+class DummyMsgWindow {
+ QueryInterface = ChromeUtils.generateQI([
+ "nsIMsgWindow",
+ "nsISupportsWeakReference",
+ ]);
+
+ constructor() {
+ this._deferredPromise = PromiseUtils.defer();
+ }
+
+ get statusFeedback() {
+ let scopedThis = this;
+ return {
+ startMeteors() {},
+ stopMeteors() {
+ scopedThis._deferredPromise.resolve(true);
+ },
+ showProgress() {},
+ };
+ }
+
+ get promptDialog() {
+ return alertUtilsPrompts;
+ }
+
+ deferPromise() {
+ this._deferredPromise = PromiseUtils.defer();
+ }
+
+ get promise() {
+ return this._deferredPromise.promise;
+ }
+}
+
+/* exported alert, confirmEx */
+// Prompts for cancel.
+function alertPS(parent, title, text) {}
+function confirmExPS(parent, title, text, flags) {
+ return 0;
+}