summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/test/resources/IMAPpump.jsm
blob: 3f4b55266d7adeb0f01f90474cc79d0959d13289 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* 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/. */

/*
 * This file provides a simple interface to the imap fake server. Demonstration
 *  of its use can be found in test_imapPump.js
 *
 * The code that forms the core of this file, in its original incarnation,
 *  was test_imapFolderCopy.js  There have been several iterations since
 *  then.
 */

var EXPORTED_SYMBOLS = ["IMAPPump", "setupIMAPPump", "teardownIMAPPump"];

var { MailServices } = ChromeUtils.import(
  "resource:///modules/MailServices.jsm"
);
var { localAccountUtils } = ChromeUtils.import(
  "resource://testing-common/mailnews/LocalAccountUtils.jsm"
);
var { gThreadManager, nsMailServer } = ChromeUtils.import(
  "resource://testing-common/mailnews/Maild.jsm"
);
var Imapd = ChromeUtils.import("resource://testing-common/mailnews/Imapd.jsm");
var { updateAppInfo } = ChromeUtils.importESModule(
  "resource://testing-common/AppInfo.sys.mjs"
);

// define globals
var IMAPPump = {
  daemon: null, // the imap fake server daemon
  server: null, // the imap fake server
  incomingServer: null, // nsIMsgIncomingServer for the imap server
  inbox: null, // nsIMsgFolder/nsIMsgImapMailFolder for imap inbox
  mailbox: null, // imap fake server mailbox
};

function setupIMAPPump(extensions) {
  // Create Application info if we need it.
  updateAppInfo();

  // These are copied from imap's head_server.js to here so we can run
  //   this from any directory.
  function makeServer(daemon, infoString) {
    if (infoString in Imapd.configurations) {
      return makeServer(daemon, Imapd.configurations[infoString].join(","));
    }

    function createHandler(d) {
      var handler = new Imapd.IMAP_RFC3501_handler(d);
      if (!infoString) {
        infoString = "RFC2195";
      }

      var parts = infoString.split(/ *, */);
      for (var part of parts) {
        Imapd.mixinExtension(handler, Imapd["IMAP_" + part + "_extension"]);
      }
      return handler;
    }
    var server = new nsMailServer(createHandler, daemon);
    server.start();
    return server;
  }

  function createLocalIMAPServer() {
    let server = localAccountUtils.create_incoming_server(
      "imap",
      IMAPPump.server.port,
      "user",
      "password"
    );
    server.QueryInterface(Ci.nsIImapIncomingServer);
    return server;
  }

  // end copy from head_server.js

  IMAPPump.daemon = new Imapd.ImapDaemon();
  IMAPPump.server = makeServer(IMAPPump.daemon, extensions);

  IMAPPump.incomingServer = createLocalIMAPServer();

  if (!localAccountUtils.inboxFolder) {
    localAccountUtils.loadLocalMailAccount();
  }

  // We need an identity so that updateFolder doesn't fail
  let localAccount = MailServices.accounts.createAccount();
  let identity = MailServices.accounts.createIdentity();
  localAccount.addIdentity(identity);
  localAccount.defaultIdentity = identity;
  localAccount.incomingServer = localAccountUtils.incomingServer;

  // Let's also have another account, using the same identity
  let imapAccount = MailServices.accounts.createAccount();
  imapAccount.addIdentity(identity);
  imapAccount.defaultIdentity = identity;
  imapAccount.incomingServer = IMAPPump.incomingServer;
  MailServices.accounts.defaultAccount = imapAccount;

  // The server doesn't support more than one connection
  Services.prefs.setIntPref("mail.server.default.max_cached_connections", 1);
  // We aren't interested in downloading messages automatically
  Services.prefs.setBoolPref("mail.server.default.download_on_biff", false);
  Services.prefs.setBoolPref("mail.biff.play_sound", false);
  Services.prefs.setBoolPref("mail.biff.show_alert", false);
  Services.prefs.setBoolPref("mail.biff.show_tray_icon", false);
  Services.prefs.setBoolPref("mail.biff.animate_dock_icon", false);
  Services.prefs.setBoolPref("mail.biff.alert.show_preview", false);

  IMAPPump.incomingServer.performExpand(null);

  IMAPPump.inbox = IMAPPump.incomingServer.rootFolder.getChildNamed("INBOX");
  IMAPPump.mailbox = IMAPPump.daemon.getMailbox("INBOX");
  IMAPPump.inbox instanceof Ci.nsIMsgImapMailFolder;
}

// This will clear not only the imap accounts but also local accounts.
function teardownIMAPPump() {
  // try to finish any pending operations
  let thread = gThreadManager.currentThread;
  while (thread.hasPendingEvents()) {
    thread.processNextEvent(true);
  }

  IMAPPump.inbox = null;
  try {
    let serverSink = IMAPPump.incomingServer.QueryInterface(
      Ci.nsIImapServerSink
    );
    serverSink.abortQueuedUrls();
    IMAPPump.incomingServer.closeCachedConnections();
    IMAPPump.server.resetTest();
    IMAPPump.server.stop();
    MailServices.accounts.removeIncomingServer(IMAPPump.incomingServer, false);
    IMAPPump.incomingServer = null;
    localAccountUtils.clearAll();
  } catch (ex) {
    dump(ex);
  }
}