Tabelle imap_account_mails, Importer schreibt die Zuordnung auch bei Duplikaten, Zugriffsregel und Index-Tokens nutzen sie, archivmail imap-link befüllt den Bestand (Trockenlauf Standard, --apply schreibt nur die Zuordnung). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
102 lines
3.2 KiB
Go
102 lines
3.2 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"regexp"
|
|
"slices"
|
|
"testing"
|
|
)
|
|
|
|
func TestImapAccountToken(t *testing.T) {
|
|
re := regexp.MustCompile(`^imapacct[1-9][0-9]*$`)
|
|
for _, id := range []int64{1, 7, 42, 1234567890} {
|
|
tok := ImapAccountToken(id)
|
|
if !re.MatchString(tok) {
|
|
t.Errorf("%d: token %q does not satisfy the index format", id, tok)
|
|
}
|
|
}
|
|
if ImapAccountToken(42) != "imapacct42" {
|
|
t.Errorf("got %q", ImapAccountToken(42))
|
|
}
|
|
for _, id := range []int64{0, -1} {
|
|
if tok := ImapAccountToken(id); tok != "" {
|
|
t.Errorf("%d: invalid id must yield no token, got %q", id, tok)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMailSourceAccountToken(t *testing.T) {
|
|
id := func(v int64) *int64 { return &v }
|
|
tests := []struct {
|
|
src MailSource
|
|
want string
|
|
}{
|
|
{MailSource{Type: "imap", ID: id(3)}, "imapacct3"},
|
|
{MailSource{Type: "imap"}, ""},
|
|
{MailSource{Type: "pop3", ID: id(3)}, ""},
|
|
{MailSource{Type: "smtp"}, ""},
|
|
{MailSource{Type: "import", ID: id(3)}, ""},
|
|
{MailSource{}, ""},
|
|
{MailSource{Type: "imap", ID: id(0)}, ""},
|
|
}
|
|
for _, tt := range tests {
|
|
if got := tt.src.AccountToken(); got != tt.want {
|
|
t.Errorf("%+v: got %q, want %q", tt.src, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestOwnerIdentities(t *testing.T) {
|
|
if got := ownerIdentities(" Alice ", "ALICE@Example.com"); !slices.Equal(got, []string{"alice", "alice@example.com"}) {
|
|
t.Errorf("got %v", got)
|
|
}
|
|
if got := ownerIdentities("bob@example.com", "Bob@example.com"); !slices.Equal(got, []string{"bob@example.com"}) {
|
|
t.Errorf("duplicate identity: got %v", got)
|
|
}
|
|
if got := ownerIdentities(" ", ""); got != nil {
|
|
t.Errorf("blank identities must yield nothing, got %v", got)
|
|
}
|
|
}
|
|
|
|
func TestImapAccountIDsForOwnerWithoutDB(t *testing.T) {
|
|
s := &Store{}
|
|
ids, err := s.ImapAccountIDsForOwner(context.Background(), "alice", "alice@example.com", nil)
|
|
if err != nil || ids != nil {
|
|
t.Errorf("got (%v, %v)", ids, err)
|
|
}
|
|
if rcpt := s.DeliveryRcpt(context.Background(), "x", nil, nil); rcpt != "" {
|
|
t.Errorf("no DB must yield no rcpt, got %q", rcpt)
|
|
}
|
|
}
|
|
|
|
func TestMailSourceAccountTokensWithLinks(t *testing.T) {
|
|
id := func(v int64) *int64 { return &v }
|
|
tests := []struct {
|
|
name string
|
|
src MailSource
|
|
want []string
|
|
}{
|
|
{"source only", MailSource{Type: "imap", ID: id(3)}, []string{"imapacct3"}},
|
|
{"links without source", MailSource{Linked: []int64{12, 4}}, []string{"imapacct4", "imapacct12"}},
|
|
{"source plus links, deduplicated", MailSource{Type: "imap", ID: id(4), Linked: []int64{12, 4, 4}}, []string{"imapacct4", "imapacct12"}},
|
|
{"pop3 source is no account", MailSource{Type: "pop3", ID: id(4), Linked: []int64{7}}, []string{"imapacct7"}},
|
|
{"invalid link ids", MailSource{Linked: []int64{0, -1}}, []string{}},
|
|
{"nothing", MailSource{}, []string{}},
|
|
}
|
|
for _, tt := range tests {
|
|
if got := tt.src.AccountTokens(); !slices.Equal(got, tt.want) {
|
|
t.Errorf("%s: got %v, want %v", tt.name, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestLinkedImapAccountsWithoutDB(t *testing.T) {
|
|
s := &Store{}
|
|
if ids, err := s.LinkedImapAccounts(context.Background(), "x"); err != nil || ids != nil {
|
|
t.Errorf("got (%v, %v)", ids, err)
|
|
}
|
|
if m, err := s.LinkedImapAccountsBatch(context.Background(), []string{"x"}); err != nil || len(m) != 0 {
|
|
t.Errorf("got (%v, %v)", m, err)
|
|
}
|
|
}
|