- Introduced a new sync pipeline for IMAP that integrates a rules engine and webhook execution. - Enhanced the `SyncWorker` to support attachment management and folder synchronization. - Added functionality to detect special folder types (Sent, Drafts, Trash, Archive, Spam) during sync. - Implemented a database schema for tracking rule executions and their outcomes. - Created unit tests for the new rules engine and webhook execution logic. - Updated migration scripts to accommodate new database structures for rule executions and folder states. - Enhanced error handling and logging throughout the sync process for better observability.
244 lines
5.0 KiB
Go
244 lines
5.0 KiB
Go
package imap
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/emersion/go-imap/v2"
|
|
)
|
|
|
|
func TestDetectFolderType(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
mailbox string
|
|
attrs []imap.MailboxAttr
|
|
want string
|
|
}{
|
|
{
|
|
name: "noselect returns empty",
|
|
mailbox: "Notes",
|
|
attrs: []imap.MailboxAttr{imap.MailboxAttrNoSelect},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "noselect skipped even with sent name",
|
|
mailbox: "Sent",
|
|
attrs: []imap.MailboxAttr{imap.MailboxAttrNoSelect, imap.MailboxAttrSent},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "attr sent",
|
|
mailbox: "Outbox",
|
|
attrs: []imap.MailboxAttr{imap.MailboxAttrSent},
|
|
want: "sent",
|
|
},
|
|
{
|
|
name: "attr drafts",
|
|
mailbox: "Brouillons",
|
|
attrs: []imap.MailboxAttr{imap.MailboxAttrDrafts},
|
|
want: "drafts",
|
|
},
|
|
{
|
|
name: "attr trash",
|
|
mailbox: "Corbeille",
|
|
attrs: []imap.MailboxAttr{imap.MailboxAttrTrash},
|
|
want: "trash",
|
|
},
|
|
{
|
|
name: "attr archive",
|
|
mailbox: "Old",
|
|
attrs: []imap.MailboxAttr{imap.MailboxAttrArchive},
|
|
want: "archive",
|
|
},
|
|
{
|
|
name: "attr junk",
|
|
mailbox: "Bulk",
|
|
attrs: []imap.MailboxAttr{imap.MailboxAttrJunk},
|
|
want: "spam",
|
|
},
|
|
{
|
|
name: "attrs beat heuristics",
|
|
mailbox: "INBOX",
|
|
attrs: []imap.MailboxAttr{imap.MailboxAttrSent},
|
|
want: "sent",
|
|
},
|
|
{
|
|
name: "inbox heuristic",
|
|
mailbox: "INBOX",
|
|
attrs: nil,
|
|
want: "inbox",
|
|
},
|
|
{
|
|
name: "inbox lowercase",
|
|
mailbox: "inbox",
|
|
attrs: nil,
|
|
want: "inbox",
|
|
},
|
|
{
|
|
name: "sent heuristic",
|
|
mailbox: "Sent",
|
|
attrs: nil,
|
|
want: "sent",
|
|
},
|
|
{
|
|
name: "sent items heuristic",
|
|
mailbox: "Sent Items",
|
|
attrs: nil,
|
|
want: "sent",
|
|
},
|
|
{
|
|
name: "sent messages heuristic",
|
|
mailbox: "Sent Messages",
|
|
attrs: nil,
|
|
want: "sent",
|
|
},
|
|
{
|
|
name: "gmail sent heuristic",
|
|
mailbox: "[Gmail]/Sent Mail",
|
|
attrs: nil,
|
|
want: "sent",
|
|
},
|
|
{
|
|
name: "inbox dot sent heuristic",
|
|
mailbox: "INBOX.Sent",
|
|
attrs: nil,
|
|
want: "sent",
|
|
},
|
|
{
|
|
name: "drafts heuristic",
|
|
mailbox: "Drafts",
|
|
attrs: nil,
|
|
want: "drafts",
|
|
},
|
|
{
|
|
name: "gmail drafts heuristic",
|
|
mailbox: "[Gmail]/Drafts",
|
|
attrs: nil,
|
|
want: "drafts",
|
|
},
|
|
{
|
|
name: "trash heuristic",
|
|
mailbox: "Trash",
|
|
attrs: nil,
|
|
want: "trash",
|
|
},
|
|
{
|
|
name: "deleted heuristic",
|
|
mailbox: "Deleted",
|
|
attrs: nil,
|
|
want: "trash",
|
|
},
|
|
{
|
|
name: "gmail trash heuristic",
|
|
mailbox: "[Gmail]/Trash",
|
|
attrs: nil,
|
|
want: "trash",
|
|
},
|
|
{
|
|
name: "archive heuristic",
|
|
mailbox: "Archive",
|
|
attrs: nil,
|
|
want: "archive",
|
|
},
|
|
{
|
|
name: "all mail heuristic",
|
|
mailbox: "All Mail",
|
|
attrs: nil,
|
|
want: "archive",
|
|
},
|
|
{
|
|
name: "gmail all mail heuristic",
|
|
mailbox: "[Gmail]/All Mail",
|
|
attrs: nil,
|
|
want: "archive",
|
|
},
|
|
{
|
|
name: "junk heuristic",
|
|
mailbox: "Junk",
|
|
attrs: nil,
|
|
want: "spam",
|
|
},
|
|
{
|
|
name: "spam heuristic",
|
|
mailbox: "Spam",
|
|
attrs: nil,
|
|
want: "spam",
|
|
},
|
|
{
|
|
name: "gmail spam heuristic",
|
|
mailbox: "[Gmail]/Spam",
|
|
attrs: nil,
|
|
want: "spam",
|
|
},
|
|
{
|
|
name: "custom folder",
|
|
mailbox: "Work/Projects",
|
|
attrs: nil,
|
|
want: "custom",
|
|
},
|
|
{
|
|
name: "leaf sent in hierarchy",
|
|
mailbox: "Accounts/Sent",
|
|
attrs: nil,
|
|
want: "sent",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := DetectFolderType(tt.mailbox, tt.attrs)
|
|
if got != tt.want {
|
|
t.Fatalf("DetectFolderType(%q, %v) = %q, want %q", tt.mailbox, tt.attrs, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDisplayName(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
mailbox string
|
|
folderType string
|
|
want string
|
|
}{
|
|
{name: "inbox type", mailbox: "INBOX", folderType: "inbox", want: "Inbox"},
|
|
{name: "sent type", mailbox: "[Gmail]/Sent Mail", folderType: "sent", want: "Sent"},
|
|
{name: "drafts type", mailbox: "Drafts", folderType: "drafts", want: "Drafts"},
|
|
{name: "trash type", mailbox: "Trash", folderType: "trash", want: "Trash"},
|
|
{name: "archive type", mailbox: "All Mail", folderType: "archive", want: "Archive"},
|
|
{name: "spam type", mailbox: "Junk", folderType: "spam", want: "Spam"},
|
|
{
|
|
name: "custom uses leaf",
|
|
mailbox: "Work/Projects",
|
|
folderType: "custom",
|
|
want: "Projects",
|
|
},
|
|
{
|
|
name: "unknown type uses leaf",
|
|
mailbox: "Clients/ACME",
|
|
folderType: "",
|
|
want: "ACME",
|
|
},
|
|
{
|
|
name: "dot hierarchy leaf",
|
|
mailbox: "INBOX.Work",
|
|
folderType: "custom",
|
|
want: "Work",
|
|
},
|
|
{
|
|
name: "custom type casing ignored",
|
|
mailbox: "Reports/Q1",
|
|
folderType: "CUSTOM",
|
|
want: "Q1",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := DisplayName(tt.mailbox, tt.folderType)
|
|
if got != tt.want {
|
|
t.Fatalf("DisplayName(%q, %q) = %q, want %q", tt.mailbox, tt.folderType, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|