summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/base/test/unit/test_copyToInvalidDB.js
blob: 2c0dd85d9fb86e85a27ffea588fa1239171b0973 (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
/*
 * Simple tests for copying local messages to a folder whose db is missing
 * or invalid
 */

const { PromiseTestUtils } = ChromeUtils.import(
  "resource://testing-common/mailnews/PromiseTestUtils.jsm"
);

const { MessageGenerator } = ChromeUtils.import(
  "resource://testing-common/mailnews/MessageGenerator.jsm"
);

async function setup() {
  let createSubfolder = async function (parentFolder, name) {
    let promiseAdded = PromiseTestUtils.promiseFolderAdded(name);
    parentFolder.createSubfolder(name, null);
    await promiseAdded;
    return parentFolder.getChildNamed(name);
  };

  // Create account.
  MailServices.accounts.createLocalMailAccount();
  let account = MailServices.accounts.FindAccountForServer(
    MailServices.accounts.localFoldersServer
  );
  let root = account.incomingServer.rootFolder;

  // Add a couple of folders containing some test messages.
  let folder1 = await createSubfolder(root, "test1");
  folder1.QueryInterface(Ci.nsIMsgLocalMailFolder);

  let folder2 = await createSubfolder(root, "test2");
  folder2.QueryInterface(Ci.nsIMsgLocalMailFolder);

  let gen = new MessageGenerator();
  let msg1 = gen.makeMessage();
  let msg2 = gen.makeMessage({ inReplyTo: msg1 });
  folder1.addMessageBatch([msg1, msg2].map(m => m.toMboxString()));

  let msg3 = gen.makeMessage();
  folder2.addMessage(msg3.toMboxString());

  return [folder1, folder2];
}

add_task(async function test_copyToInvalidDB() {
  let [folder1, folder2] = await setup();

  // folder1 contains [msg1, msg2].
  // folder2 contains [msg3].

  // Take note of the message we're going to move (first msg in folder1).
  let msgHdr = Array.from(folder1.msgDatabase.enumerateMessages())[0];
  let expectedID = msgHdr.messageId;
  let expectedMsg = mailTestUtils.loadMessageToString(folder1, msgHdr);

  // Sabotage the destination folder2 database.
  folder2.msgDatabase.summaryValid = false;
  folder2.msgDatabase = null;
  folder2.ForceDBClosed();
  // In fact, delete the .msf file entirely.
  folder2.summaryFile.remove(false);

  // So folder2 has no trace of a DB.
  Assert.equal(folder2.databaseOpen, false);
  Assert.equal(folder2.summaryFile.exists(), false);

  // Move the message from folder1 to folder2.
  let copyListener = new PromiseTestUtils.PromiseCopyListener();
  MailServices.copy.copyMessages(
    folder1,
    [msgHdr],
    folder2,
    true, // isMove
    copyListener,
    null, // window
    false // allowUndo
  );
  await copyListener.promise;

  // Current behaviour:
  // After the move, there's still no sign of a DB file.
  // Yet the copy didn't fail (see Bug 1737203).
  Assert.equal(folder2.databaseOpen, false);
  Assert.equal(folder2.summaryFile.exists(), false);

  // Rebuild the the database.
  let urlListener = new PromiseTestUtils.PromiseUrlListener();
  try {
    folder2.getDatabaseWithReparse(urlListener, null);
  } catch (ex) {
    // We expect this - it indicates the DB is not valid. But it will have
    // kicked off an async reparse, so we need to wait for the listener.
    Assert.equal(ex.result, Cr.NS_ERROR_NOT_INITIALIZED);
    await urlListener.promise;
  }

  // Check that the message moved over intact.
  let gotHdr = folder2.msgDatabase.getMsgHdrForMessageID(expectedID);
  let gotMsg = mailTestUtils.loadMessageToString(folder2, gotHdr);
  // NOTE: With maildir store, the message seems to gain an extra trailing
  // "\n" during the copy. See Bug 1716651.
  // For now, use .trim() as a workaround.
  Assert.equal(gotMsg.trim(), expectedMsg.trim());
});