summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/imap/test/unit/test_imapHighWater.js
blob: 3fcd4bcc23cfaf561463410536816c8aeab8116d (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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/* 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/. */

/* import-globals-from ../../../test/resources/alertTestUtils.js */
load("../../../resources/alertTestUtils.js");

var { MailServices } = ChromeUtils.import(
  "resource:///modules/MailServices.jsm"
);
var { MessageGenerator, MessageScenarioFactory } = ChromeUtils.import(
  "resource://testing-common/mailnews/MessageGenerator.jsm"
);
var { PromiseTestUtils } = ChromeUtils.import(
  "resource://testing-common/mailnews/PromiseTestUtils.jsm"
);

var gIMAPDaemon, gServer, gIMAPIncomingServer;

var gIMAPInbox;
var gFolder1, gRootFolder;

// Adds some messages directly to a mailbox (eg new mail)
function addMessagesToServer(messages, mailbox) {
  // Create the ImapMessages and store them on the mailbox
  messages.forEach(function (message) {
    let dataUri = Services.io.newURI(
      "data:text/plain;base64," + btoa(message.toMessageString())
    );
    mailbox.addMessage(new ImapMessage(dataUri.spec, mailbox.uidnext++, []));
  });
}

add_setup(function () {
  localAccountUtils.loadLocalMailAccount();

  /*
   * Set up an IMAP server.
   */
  gIMAPDaemon = new ImapDaemon();
  gServer = makeServer(gIMAPDaemon, "");
  gIMAPDaemon.createMailbox("folder 1", { subscribed: true });
  gIMAPIncomingServer = createLocalIMAPServer(gServer.port);
  gIMAPIncomingServer.maximumConnectionsNumber = 1;

  // 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 = gIMAPIncomingServer;
  MailServices.accounts.defaultAccount = imapAccount;

  // pref tuning: one connection only, turn off notifications
  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.server.default.autosync_offline_stores",
    false
  );
  // Don't prompt about offline download when going offline
  Services.prefs.setIntPref("offline.download.download_messages", 2);
});

add_setup(function () {
  // make 10 messages
  let messageGenerator = new MessageGenerator();
  let scenarioFactory = new MessageScenarioFactory(messageGenerator);

  // build up a list of messages
  let messages = [];
  messages = messages.concat(scenarioFactory.directReply(10));

  // Add 10 messages with uids 1-10.
  let imapInbox = gIMAPDaemon.getMailbox("INBOX");
  addMessagesToServer(messages, imapInbox);
  messages = [];
  messages = messages.concat(messageGenerator.makeMessage());
  // Add a single message to move target folder.
  addMessagesToServer(messages, gIMAPDaemon.getMailbox("folder 1"));

  // Get the IMAP inbox...
  gRootFolder = gIMAPIncomingServer.rootFolder;
  gIMAPInbox = gRootFolder
    .getFolderWithFlags(Ci.nsMsgFolderFlags.Inbox)
    .QueryInterface(Ci.nsIMsgImapMailFolder);
});

add_task(async function doMoves() {
  // update folders to download headers.
  let urlListenerInbox = new PromiseTestUtils.PromiseUrlListener();
  gIMAPInbox.updateFolderWithListener(null, urlListenerInbox);
  await urlListenerInbox.promise;
  gFolder1 = gRootFolder
    .getChildNamed("folder 1")
    .QueryInterface(Ci.nsIMsgImapMailFolder);
  let urlListenerFolder1 = new PromiseTestUtils.PromiseUrlListener();
  gFolder1.updateFolderWithListener(null, urlListenerFolder1);
  await urlListenerFolder1.promise;
  // get five messages to move from Inbox to folder 1.
  let headers1 = [];
  let count = 0;
  for (let header of gIMAPInbox.msgDatabase.enumerateMessages()) {
    if (count >= 5) {
      break;
    }
    if (header instanceof Ci.nsIMsgDBHdr) {
      headers1.push(header);
    }
    count++;
  }
  // this will add dummy headers with keys > 0xffffff80
  let copyListenerDummyHeaders = new PromiseTestUtils.PromiseCopyListener();
  MailServices.copy.copyMessages(
    gIMAPInbox,
    headers1,
    gFolder1,
    true,
    copyListenerDummyHeaders,
    gDummyMsgWindow,
    true
  );
  await copyListenerDummyHeaders.promise;

  let urlListenerInboxAfterDummy = new PromiseTestUtils.PromiseUrlListener();
  gIMAPInbox.updateFolderWithListener(null, urlListenerInboxAfterDummy);
  await urlListenerInboxAfterDummy.promise;

  let urlListenerFolder1AfterDummy = new PromiseTestUtils.PromiseUrlListener();
  gFolder1.updateFolderWithListener(
    gDummyMsgWindow,
    urlListenerFolder1AfterDummy
  );
  await urlListenerFolder1AfterDummy.promise;

  // Check that playing back offline events gets rid of dummy
  // headers, and thus highWater is recalculated.
  Assert.equal(gFolder1.msgDatabase.dBFolderInfo.highWater, 6);
  headers1 = [];
  count = 0;
  for (let header of gIMAPInbox.msgDatabase.enumerateMessages()) {
    if (count >= 5) {
      break;
    }
    if (header instanceof Ci.nsIMsgDBHdr) {
      headers1.push(header);
    }
    count++;
  }
  // Check that copyMessages will handle having a high highwater mark.
  // It will thrown an exception if it can't.
  let msgHdr = gFolder1.msgDatabase.createNewHdr(0xfffffffd);
  gFolder1.msgDatabase.addNewHdrToDB(msgHdr, false);
  let copyListenerHighWater = new PromiseTestUtils.PromiseCopyListener();
  MailServices.copy.copyMessages(
    gIMAPInbox,
    headers1,
    gFolder1,
    true,
    copyListenerHighWater,
    gDummyMsgWindow,
    true
  );
  await copyListenerHighWater.promise;
  gServer.performTest("UID COPY");

  gFolder1.msgDatabase.deleteHeader(msgHdr, null, true, false);
  let urlListenerInboxAfterDelete = new PromiseTestUtils.PromiseUrlListener();
  gIMAPInbox.updateFolderWithListener(null, urlListenerInboxAfterDelete);
  await urlListenerInboxAfterDelete.promise;
  // this should clear the dummy headers.
  let urlListenerFolder1AfterDelete = new PromiseTestUtils.PromiseUrlListener();
  gFolder1.updateFolderWithListener(
    gDummyMsgWindow,
    urlListenerFolder1AfterDelete
  );
  await urlListenerFolder1AfterDelete.promise;
  Assert.equal(gFolder1.msgDatabase.dBFolderInfo.highWater, 11);
});

add_task(function endTest() {
  Services.io.offline = true;
  gServer.performTest("LOGOUT");
  gIMAPIncomingServer.closeCachedConnections();
  gServer.stop();
});