mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-11-15 14:20:38 +08:00
574f171fbd
Summary: We can't try to set or remove the sent label on gmail accounts because the operation will silently fail and cause the threads to later bounce back. This occurred when trying to delete or archive a thread that contained a sent message, and we incorrectly tried to overwrite or remove all of the labels on messages, without regard for sent. This was causing https://github.com/nylas/nylas-mail/issues/2706 and sending and archiving to immediately bounce back. Addresses T7757 Test Plan: unit tests Reviewers: halla, evan, spang Reviewed By: halla, evan, spang Differential Revision: https://phab.nylas.com/D3829
163 lines
5.5 KiB
JavaScript
163 lines
5.5 KiB
JavaScript
import {
|
|
ACCOUNT_ID,
|
|
mockImapBox,
|
|
getTestDatabase,
|
|
} from '../helpers'
|
|
import IMAPHelpers from '../../src/local-sync-worker/imap-helpers'
|
|
|
|
describe('IMAPHelpers', function describeBlock() {
|
|
describe('setLabelsForMessages', () => {
|
|
beforeEach(async () => {
|
|
this.db = await getTestDatabase()
|
|
this.sentLabel = await this.db.Label.create({
|
|
id: 'sent',
|
|
accountId: ACCOUNT_ID,
|
|
name: '\\Sent',
|
|
role: 'sent',
|
|
})
|
|
this.l1 = await this.db.Label.create({
|
|
id: 'l1',
|
|
name: 'l1',
|
|
accountId: ACCOUNT_ID,
|
|
})
|
|
this.l2 = await this.db.Label.create({
|
|
id: 'l2',
|
|
name: 'l2',
|
|
accountId: ACCOUNT_ID,
|
|
})
|
|
this.l3 = await this.db.Label.create({
|
|
id: 'l3',
|
|
name: 'l3',
|
|
accountId: ACCOUNT_ID,
|
|
})
|
|
|
|
this.m1 = await this.db.Message.create({
|
|
id: 'm1',
|
|
folderImapUID: 1,
|
|
accountId: ACCOUNT_ID,
|
|
})
|
|
await this.m1.setLabels(['l1', 'l2'])
|
|
this.m1.labels = ['l1', 'l2']
|
|
|
|
this.m2 = await this.db.Message.create({
|
|
id: 'm2',
|
|
folderImapUID: 2,
|
|
accountId: ACCOUNT_ID,
|
|
})
|
|
await this.m2.setLabels(['l1', 'l2'])
|
|
this.m2.labels = ['l1', 'l2']
|
|
|
|
this.m3 = await this.db.Message.create({
|
|
id: 'm3',
|
|
folderImapUID: 3,
|
|
accountId: ACCOUNT_ID,
|
|
})
|
|
await this.m3.setLabels(['l1'])
|
|
this.m3.labels = ['l1']
|
|
|
|
this.messages = [this.m1, this.m2, this.m3]
|
|
const messagesByUID = {
|
|
1: this.m1,
|
|
2: this.m2,
|
|
3: this.m3,
|
|
}
|
|
this.box = mockImapBox()
|
|
this.box.removeLabels.andCallFake(async (uids, labelsToRemove) => {
|
|
if (!labelsToRemove || typeof labelsToRemove === 'string' || labelsToRemove.length === 0) {
|
|
throw new Error('labelsToRemove must be a non-empty array')
|
|
}
|
|
for (const uid of uids) {
|
|
const msg = messagesByUID[uid]
|
|
msg.labels = msg.labels.filter(l => !labelsToRemove.includes(l))
|
|
}
|
|
})
|
|
this.box.setLabels.andCallFake(async (uids, labelsToSet) => {
|
|
if (!labelsToSet || typeof labelsToSet === 'string' || labelsToSet.length === 0) {
|
|
throw new Error('labelsToSet must be a non-empty array')
|
|
}
|
|
for (const uid of uids) {
|
|
const msg = messagesByUID[uid]
|
|
msg.labels = labelsToSet
|
|
}
|
|
})
|
|
})
|
|
|
|
it('removes all labels for each message if labelIds is empty', async () => {
|
|
const labelIds = []
|
|
await IMAPHelpers.setLabelsForMessages({db: this.db, box: this.box, messages: this.messages, labelIds})
|
|
for (const msg of this.messages) {
|
|
expect(msg.labels.length).toBe(0)
|
|
}
|
|
});
|
|
|
|
it('does not remove the sent label from messages when removing all labels', async () => {
|
|
await this.m3.addLabel(this.sentLabel)
|
|
this.m3.labels.push(this.sentLabel.imapLabelIdentifier())
|
|
|
|
const labelIds = []
|
|
await IMAPHelpers.setLabelsForMessages({db: this.db, box: this.box, messages: this.messages, labelIds})
|
|
|
|
expect(this.m1.labels.length).toBe(0)
|
|
expect(this.m2.labels.length).toBe(0)
|
|
expect(this.m3.labels.length).toBe(1)
|
|
expect(this.m3.labels[0]).toEqual(this.sentLabel.imapLabelIdentifier())
|
|
});
|
|
|
|
it('does not try to remove labels if none present', async () => {
|
|
await this.m1.setLabels([])
|
|
this.m1.labels = []
|
|
await this.m3.setLabels([this.sentLabel])
|
|
this.m3.labels = [this.sentLabel.imapLabelIdentifier()]
|
|
|
|
const labelIds = []
|
|
await IMAPHelpers.setLabelsForMessages({
|
|
labelIds,
|
|
db: this.db,
|
|
box: this.box,
|
|
messages: [this.m1, this.m3],
|
|
})
|
|
|
|
expect(this.box.removeLabels).not.toHaveBeenCalled()
|
|
expect(this.m1.labels.length).toBe(0)
|
|
expect(this.m3.labels.length).toBe(1)
|
|
expect(this.m3.labels[0]).toEqual(this.sentLabel.imapLabelIdentifier())
|
|
});
|
|
|
|
it('sets the provided labels', async () => {
|
|
const labelIds = ['l1', 'l3']
|
|
await IMAPHelpers.setLabelsForMessages({db: this.db, box: this.box, messages: this.messages, labelIds})
|
|
for (const msg of this.messages) {
|
|
expect(msg.labels).toEqual = labelIds
|
|
}
|
|
});
|
|
|
|
it(`keeps the sent label on messages even if it wasn't provided in the labels to set`, async () => {
|
|
await this.m3.addLabel(this.sentLabel)
|
|
this.m3.labels.push(this.sentLabel.imapLabelIdentifier())
|
|
|
|
const labelIds = ['l1', 'l3']
|
|
await IMAPHelpers.setLabelsForMessages({db: this.db, box: this.box, messages: this.messages, labelIds})
|
|
|
|
expect(this.m1.labels).toEqual(labelIds)
|
|
expect(this.m2.labels).toEqual(labelIds)
|
|
expect(this.m3.labels).toEqual([...labelIds, this.sentLabel.imapLabelIdentifier()])
|
|
});
|
|
|
|
it(`does not attempt to add the sent label to messages even if the labels to set contain the sent label`, async () => {
|
|
const labelIds = ['l1', 'l3', this.sentLabel.imapLabelIdentifier()]
|
|
await IMAPHelpers.setLabelsForMessages({db: this.db, box: this.box, messages: this.messages, labelIds})
|
|
for (const msg of this.messages) {
|
|
expect(msg.labels).toEqual = labelIds.slice(0, 2)
|
|
}
|
|
})
|
|
|
|
it(`does not attempt to set labels if no labels to set`, async () => {
|
|
await this.m1.setLabels([])
|
|
this.m1.labels = []
|
|
const labelIds = [this.sentLabel.imapLabelIdentifier()]
|
|
await IMAPHelpers.setLabelsForMessages({db: this.db, box: this.box, messages: [this.m1], labelIds})
|
|
expect(this.box.removeLabels).not.toHaveBeenCalled()
|
|
expect(this.m1.labels.length).toBe(0)
|
|
})
|
|
});
|
|
});
|